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:

Community
  • 1
  • 1
Andy
  • 1,815
  • 2
  • 22
  • 49

1 Answers1

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.

Heskja
  • 787
  • 6
  • 19
  • Hi using same code in fragment, but iam getting null at e1 in onFling method. Can you please help me ? – Gangadhar Nimballi Sep 05 '13 at 10:57
  • 1
    @GangadharNimbally You should probably start your own question where you put the complete stacktrace and your code. – Heskja Sep 30 '13 at 20:10
  • I have implemented above class, but some how it's not working for me. new MyGestureDetector(lst_sampleList); – Hitesh Dhamshaniya Jun 05 '14 at 10:18
  • 1
    Like I said, @HiteshDhamshaniya, you should probably start your own question where you can put the complete stack-trace and your code. – Heskja Jun 07 '14 at 17:58
  • 1
    @Heskja The code is working for me. But what type of condition should I put on `INSERT_CONDITIONS_HERE` ? – viper Dec 07 '16 at 04:44