2011-08-30 56 views
1

我有一個GridView的一個奇怪的問題。該GridView控件與baseAdapter:onItemClick給錯了位置

onItemClick(適配器視圖父母,視圖V,INT位置,長ID)

方法有時給錯誤的位置。 代碼我有:

public class ImageAdapter extends BaseAdapter { 
...... 
} 

gridview = (GridView) findViewById(R.id.gridview); 

image_adapter = new ImageAdapter(this); 

gridview.setAdapter(image_adapter); 

gridview.setOnItemClickListener(new OnItemClickListener() { 

      public void onItemClick(AdapterView<?> parent, View v, int position, long id) { 
       Log.e(TAG, "position = "+position); 
         } 
    } 

我GRIDVIEW是3X3格和圖像適配器具有上的圖像9片。基於用戶選擇的網格位置,圖像塊被混洗。

如果選擇的網格位置將慢慢做這工作得很好。但是,如果用戶在任何特定位置上都快速點擊,onItemClick方法中的「位置」參數將被任意更改。 假如我的網格

0 1 2 

3 4 5 

6 7 8 

和用戶不斷快步上5位攻,有時onItemClick「位置」參數讀數爲0或6

任何想法究竟是什麼原因什麼可能是解決方案?

回答

0

相反的OnItemClickListener你會使用OnItemSelectedListener

+0

我按照您的建議嘗試了OnItemSelectedListener。恐怕它不起作用。 – user556956

2

我有我的項目中同樣煩惱的好 - 也許它會幫助你。

,你可能會有的onTouchEvent在你活動的實現。讓這樣的事情:

@Override 
    public boolean onTouch(View v, MotionEvent event) { 
     // TODO Auto-generated method stub 
     switch (event.getAction()) { 
     case MotionEvent.ACTION_DOWN: 
      startX = event.getX();//probably Click 
      return false; 
     case MotionEvent.ACTION_UP: 
      float currentX = event.getX(); 
      if (this.startX-MOVE_DENSITY > currentX) { 
       //fling right 
          return true; 
      } 
      if (this.startX+MOVE_DENSITY < currentX) { 
       //fling left 
       return true; 
      } 
      default: 
      return false; 
     } 
    } 

這是非常重要的一個返回值!你必須在你的課堂上有一個字段double startX,並且常量MOVE_DENSITY,這意味着密度來檢測投擲移動(在我的情況下,我把它設置爲50)。也許不是很好的解釋,但我的英語不好))希望它可以幫助你!

0

我有這樣一個問題。我不知道你是否設置了gridview.setEnabledtruefalse,但我做到了。如果用戶在gridview.setEnabled觸發器之前和之下點擊該項目,gridview有時會讓你錯誤的位置。

爲了解決這個我上,我設置爲走了,可見在GridView的頂部由透明RelativeLayout。 RelativeLayout必須是android:clickable="true"

0

基於維亞切的答案,我做了一些修改。

在我自己的類(定製GridView控件):

public class CustomGridView extends GridView { 
    private int position = -1; 
    private float xCoor, yCoor; 
    private Context context; 
    private Drawable defaultDrawable; 
    //Constructors - Skipped 
    public void setInitPosition(int position, float x, float y) { 
     this.position = position; 
     this.xCoor = x; 
     this.yCoor = y; 
     defaultDrawable = this.getChildAt(position - this.getFirstVisiblePosition()).getBackground(); 
     this.getChildAt(position - this.getFirstVisiblePosition()).setBackgroundColor(Color.RED/*For Example*/)); 
    } 

    @Override 
    public boolean performClick() { 
     return super.performClick(); 
    } 

    public int getInitialPosition() { 
     if(position != -1) { 
      if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { 
       this.getChildAt(position - this.getFirstVisiblePosition()).setBackground(defaultDrawable); 
      } else { 
       this.getChildAt(position - this.getFirstVisiblePosition()).setBackgroundColor(context.getResources().getColor(R.color.grid_selection_item_background)); 
      } 
     } 
     return position; 
    } 
    public float xCoor() { 
     return xCoor; 
    } 

    public float yCoor() { 
     return yCoor; 
    } 
} 

在你onTouchListener:

CustomGridView gridView; 
...  

@Override 
public boolean onTouch(View v, MotionEvent event) { 
    v.performClick(); 
    int action = event.getActionMasked(); 
    float xPosition = event.getX(); 
    float yPosition = event.getY(); 
    int position = listView.pointToPosition((int) xPosition, (int) yPosition); 
    if(position != AbsListView.INVALID_POSITION) { 
     if(action == MotionEvent.ACTION_DOWN) { 
      gridView.setInitialPosition(position, xPosition, yPosition); 
     } 
     if(action == MotionEvent.ACTION_UP) { 
      int checkedPosition = gridView.getInitialPosition(); 
      if(checkedPosition == position) { 
       if(Math.abs(yPosition - gridView.yCoor()) < 10/*Your fling "density"*/) { 
        doYourAction(position); 
       } 
      } 
     } 
    } 
    return detector.onTouchEvent(event); 
} 

在onTouch回調位置,是項目在GridView的位置,無法查看位置。查看位置必須扣除gridView.getFirstVisiblePosition()