Showing a delete button on swipe in a listview for Android
Asked Answered
P

1

6

Expanding on another Stackoverflow question, I've implemented some gesture detection code so that I can detect when a row in my listview (which is in a FrameLayout) has been swiped. I followed the question/answer by Damian here about how to get the individual row/view from the adapter. How to get location (on screen) of row in listview

I have code in my onFling that gets the view for the row, and tries to make a delete button that is set as invisible in my xml layout to visible. However, this doesn't happen. I was wondering how I make a button visible in a listview on a swipe?

class MyGestureDetector extends SimpleOnGestureListener {
    @Override
    public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
            float velocityY) {
        try {

            if (e2.getX() - e1.getX() > SWIPE_MIN_DISTANCE
                    && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) {
                int itemId = MyClass.this.lv.pointToPosition(
                        (int) e1.getX(), (int) e1.getY());

                Log.v("item id", String.valueOf(itemId));
                View v = MyClass.this.adapter
                        .getViewOnScreen(itemId);
                Button delete = (Button) v.findViewById(R.id.button_delete);

                delete.setVisibility(View.VISIBLE);
                //MyClass.this.adapter.notifyDataSetChanged();


            }

        } catch (Exception e) {
            // nothing
        }
        return false;
    }
}

My list adapter code is the same as the referenced question.

Edit: I tried using getChildAt() on the listview to get the row's view, and this works when there is one screen or less of items, but when there's more than the wrong view is returned and therefore the wrong delete button becomes visible.

Edit 2: I used the answer on the question here to get it to work:

Peddling answered 3/10, 2012 at 17:41 Comment(0)
D
9

I implemented something like this in my app once. The way I did it:

public class MyGestureDetector extends SimpleOnGestureListener {
    private ListView list;

    public MyGestureDetector(ListView list) {
        this.list = list;
    }

    //CONDITIONS ARE TYPICALLY VELOCITY OR DISTANCE    
    @Override
    public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
        if (INSERT_CONDITIONS_HERE)
            if (showDeleteButton(e1))
                return true;
        return super.onFling(e1, e2, velocityX, velocityY);
    }

    private boolean showDeleteButton(MotionEvent e1) {
        int pos = list.pointToPosition((int)e1.getX(), (int)e1.getY());
        return showDeleteButton(pos);
    }

    private boolean showDeleteButton(int pos) {
        View child = list.getChildAt(pos);
        if (child != null){
            Button delete = (Button) child.findViewById(R.id.delete_button_id);
            if (delete != null)
                if (delete.getVisibility() == View.INVISIBLE)
                    delete.setVisibility(View.VISIBLE);
                else
                    delete.setVisibility(View.INVISIBLE);
            return true;
        }
        return false;
    }
}

This worked for me, hope you'll get it to work or that it at least gives you some hint.

Dispassion answered 4/10, 2012 at 17:47 Comment(5)
Hi using same code in fragment, but iam getting null at e1 in onFling method. Can you please help me ?Vulnerary
@GangadharNimbally You should probably start your own question where you put the complete stacktrace and your code.Dispassion
I have implemented above class, but some how it's not working for me. new MyGestureDetector(lst_sampleList);Cystectomy
Like I said, @HiteshDhamshaniya, you should probably start your own question where you can put the complete stack-trace and your code.Dispassion
@Dispassion The code is working for me. But what type of condition should I put on INSERT_CONDITIONS_HERE ?Noheminoil

© 2022 - 2024 — McMap. All rights reserved.