我对GridView有一个奇怪的问题。
onItemClick(AdapterView父级,View 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方法中的“position”参数会被任意改变。 假设我的网格是
0 1 2
3 4 5
6 7 8
并且用户继续在第5位快速点击,有时onItemClick中的“position”参数读取0或6。
任何想法是什么原因以及解决方案是什么?
答案 0 :(得分:2)
我的项目遇到了同样的麻烦 - 也许它会帮助你。
您可能在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,这意味着密度来检测fling移动(在我的例子中,我将它设置为50)。也许不是很好的解释,但我的英语不太好))希望它对你有帮助!
答案 1 :(得分:1)
出现同样的问题,以下问题解决了这个问题:
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
答案 2 :(得分:0)
而不是OnItemClickListener
,您最好使用OnItemSelectedListener
答案 3 :(得分:0)
我遇到了类似这样的问题。我不知道您是否设置了gridview.setEnabled
true
和false
,但我做到了。如果用户在gridview.setEnabled触发器之前和之下点击疯狂的项目,则gridview有时会使你的位置错误。
为了解决这个问题,我在网格视图的顶部创建了一个透明的RelativeLayout
,我将其设置为可见。 RelativeLayout必须为android:clickable="true"
。
答案 4 :(得分:0)
根据Viacheslav的回答,我做了一些修改。
在我自己的班级(Customized 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 Callback中的位置是gridView中项目的位置,而不是视图位置。查看位置必须使用gridView.getFirstVisiblePosition()