Skip to content Skip to sidebar Skip to footer

Gridview With A Baseadapter: Onitemclick Giving Wrong Position

I have a weird problem with GridView. The onItemClick(AdapterView parent, View v, int position, long id) method is giving wrong position sometimes. The code i have: public class

Solution 1:

I've got the same trouble in my project - maybe it will helps you.

You probably have an implementation of onTouchEvent in your Activity. Make it something like this:

@Override
    public boolean onTouch(View v, MotionEvent event) {
        // TODO Auto-generated method stubswitch (event.getAction()) {
        case MotionEvent.ACTION_DOWN:
            startX = event.getX();//probably Clickreturnfalse;
        case MotionEvent.ACTION_UP:
            float currentX = event.getX();
            if (this.startX-MOVE_DENSITY > currentX) {
                //fling rightreturntrue;
            }
            if (this.startX+MOVE_DENSITY < currentX) {
                //fling leftreturntrue;
            }
            default:
            returnfalse;
        }   
    }

It's very important a returned value!!! You must have an field double startX in your class, and constant MOVE_DENSITY, which means density to detect fling move (in my case I set it to 50). Maybe not nice explanation, but my English is not well)) Hope it helps you!

Solution 2:

Had the same issue, the following solved the issue:

grid.setOnItemClickListener(newOnItemClickListener() {
        @OverridepublicvoidonItemClick(AdapterView<?> adapterView, View view, int i, long l) {
           intposition= i - grid.getNumColumns();
        }
});

I am using HeaderGridView class: https://android.googlesource.com/platform/packages/apps/Gallery2/+/idea133/src/com/android/photos/views/HeaderGridView.java

Solution 3:

Instead of OnItemClickListener you would be better of using OnItemSelectedListener

Solution 4:

I had a problem like this one. I don't know if you set gridview.setEnabledtrue and false, but I did. If the user taps the item like crazy just before and under the gridview.setEnabled triggers, the gridview will sometimes get you the wrong position.

To solve this I made a transparent RelativeLayout on top of the gridview which I set to gone and visible. The RelativeLayout must be android:clickable="true".

Solution 5:

Based on Viacheslav's answer, I made some modification.

In my own class (Customized GridView):

publicclassCustomGridViewextendsGridView{
    private int position = -1;
    private float xCoor, yCoor;
    private Context context;
    private Drawable defaultDrawable;
    //Constructors - Skippedpublic 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*/));
    }

    @Overridepublic boolean performClick() {
        returnsuper.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;
    }
}

In your 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);
}

The position in the onTouch Callback, is the position of item in the gridView, not view Position. View position have to deducted with gridView.getFirstVisiblePosition()

Post a Comment for "Gridview With A Baseadapter: Onitemclick Giving Wrong Position"