【问题标题】:GridView with a baseAdapter: onItemClick giving wrong position带有 baseAdapter 的 GridView:onItemClick 给出错误的位置
【发布时间】:2017-12-14 17:28:59
【问题描述】:

我对 GridView 有一个奇怪的问题。

onItemClick(AdapterView parent, View v, int position, long 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。

知道这是什么原因,有什么解决办法吗?

【问题讨论】:

    标签: android gridview


    【解决方案1】:

    我在我的项目中遇到了同样的问题 - 也许它会对你有所帮助。

    您可能在 Activity 中实现了 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)。也许不是很好的解释,但我的英语不好))希望它对你有帮助!

    【讨论】:

      【解决方案2】:

      遇到了同样的问题,下面解决了这个问题:

      grid.setOnItemClickListener(new OnItemClickListener() {
              @Override
              public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
                 int position = i - grid.getNumColumns();
              }
      });
      

      我正在使用 HeaderGridView 类: https://android.googlesource.com/platform/packages/apps/Gallery2/+/idea133/src/com/android/photos/views/HeaderGridView.java

      【讨论】:

        【解决方案3】:

        您最好使用OnItemSelectedListener 而不是OnItemClickListener

        【讨论】:

        • 我按照您的建议尝试了 OnItemSelectedListener。恐怕它不起作用。
        【解决方案4】:

        我遇到过这样的问题。我不知道你是否设置了gridview.setEnabledtruefalse,但我设置了。如果用户在 gridview.setEnabled 触发器之前和下方疯狂地点击该项目,gridview 有时会为您提供错误的位置。

        为了解决这个问题,我在 gridview 顶部创建了一个透明的RelativeLayout,我将其设置为消失和可见。 RelativeLayout 必须是android:clickable="true"

        【讨论】:

          【解决方案5】:

          根据维亚切斯拉夫的回答,我做了一些修改。

          在我自己的类中(自定义的 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回调中的位置,是item在gridView中的位置,不是view Position。查看位置必须用gridView.getFirstVisiblePosition()扣除

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2013-08-22
            • 2015-12-09
            • 1970-01-01
            • 2019-08-20
            • 1970-01-01
            • 2020-04-08
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多