0

I have implemented a gesture detector for my listview items, where onfling gesture is detected, two buttons will be shown. The first few list items worked fine.

However when I scroll to the bottom of my listview, onfling will not work for the last item of my listview, hence two buttons are not shown. PS: I am still able to get the position of the last list item. I am currently implementing this in my ListFragment class.

What should I do to enable onFling to work on my last list item? Thank you for any help.

Edited with the code

public class ExampleFragment extends ListFragment{
    protected GestureDetector gestureDetector;


    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        gestureDetector = new GestureDetector(getActivity(), new MyGestureDetector());
        getListView().setOnTouchListener(new OnTouchListener() {
          @Override
          public boolean onTouch(View v, MotionEvent event) {
              if (gestureDetector.onTouchEvent(event)) {
                  MotionEvent cancelEvent = MotionEvent.obtain(event);
                  cancelEvent.setAction(MotionEvent.ACTION_CANCEL);
                  v.onTouchEvent(cancelEvent);
                  return true;
              }
              return false;
          }
      });  
}

 class MyGestureDetector extends SimpleOnGestureListener {

      @Override
      public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
            int pos = getListView().pointToPosition((int)e1.getX(), (int)e1.getY());

          try {
              if (Math.abs(e1.getY() - e2.getY()) > SWIPE_MAX_OFF_PATH)
                      return false;

              if(e1.getX() - e2.getX() > SWIPE_MIN_DISTANCE && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) {
                  Toast.makeText(getActivity(), "Left Swipe", Toast.LENGTH_SHORT).show();
              }  else if (e2.getX() - e1.getX() > SWIPE_MIN_DISTANCE && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) {
                    Toast.makeText(getActivity(), "Right Swipe", Toast.LENGTH_SHORT).show();
                    View v =  getListView().getChildAt(pos);

                     if (v != null) {
                        Button edit = (Button) v.findViewById(R.id.edit);
                        Button connect = (Button) v.findViewById(R.id.connect); 
                        if (edit.getVisibility() == View.GONE && connect.getVisibility() == View.GONE){
                            edit.setVisibility(View.VISIBLE);
                               connect.setVisibility(View.VISIBLE);
                           }
                    } 

                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            return false;
        }

    }
XXX
  • 273
  • 1
  • 2
  • 9
  • where are you implementing the `onFling`... in the Activity or in the adapter class of the listView? Show us your code. – SMR Feb 25 '14 at 10:43
  • you need to fix the bug – pskink Feb 25 '14 at 10:45
  • 1
    you cannot do that: getListView().getChildAt(pos); try to Log.d number of children of your list view and pos variable – pskink Feb 25 '14 at 11:15
  • @SMR I've updated with the code included. – XXX Feb 26 '14 at 02:23
  • @pskink just did a Log.d, for the last listview item, when onFling, it shows View v : null, Positon : 7 , it seems the view returned is null, hence buttons are not shown, any ideas how to resolve this ? – XXX Feb 26 '14 at 02:27
  • @XXX see Listview.getFirstVisiblePosition – pskink Feb 26 '14 at 07:25

1 Answers1

0

@pskink, thanks to you, your comment did gave me a few thoughts, the adapter actually doesn't keep view itself, where listview keep views and pass them to the adapter. adapter will then recreate views. Below is the edited running source code, hope it helps anyone facing the same problem.

public class ExampleFragment extends ListFragment{
protected GestureDetector gestureDetector;

@Override
public void onActivityCreated(Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);
    gestureDetector = new GestureDetector(getActivity(), new MyGestureDetector());
    getListView().setOnTouchListener(new OnTouchListener() {
      @Override
      public boolean onTouch(View v, MotionEvent event) {
          if (gestureDetector.onTouchEvent(event)) {
              MotionEvent cancelEvent = MotionEvent.obtain(event);
              cancelEvent.setAction(MotionEvent.ACTION_CANCEL);
              v.onTouchEvent(cancelEvent);
              return true;
          }
          return false;
      }
  });  
}

class MyGestureDetector extends SimpleOnGestureListener {

  @Override
  public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
        int pos = getListView().pointToPosition((int)e1.getX(), (int)e1.getY());

      try {
          if (Math.abs(e1.getY() - e2.getY()) > SWIPE_MAX_OFF_PATH)
                  return false;

          if(e1.getX() - e2.getX() > SWIPE_MIN_DISTANCE && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) {
              Toast.makeText(getActivity(), "Left Swipe", Toast.LENGTH_SHORT).show();
          }  else if (e2.getX() - e1.getX() > SWIPE_MIN_DISTANCE && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) {
                Toast.makeText(getActivity(), "Right Swipe", Toast.LENGTH_SHORT).show();
                final View v = getListView().getAdapter().getView(pos, null, getListView());
                 if (v != null) {
                    Button edit = (Button) v.findViewById(R.id.edit);
                    Button connect = (Button) v.findViewById(R.id.connect); 
                    if (edit.getVisibility() == View.GONE && connect.getVisibility() == View.GONE){
                        edit.setVisibility(View.VISIBLE);
                           connect.setVisibility(View.VISIBLE);
                       }
                } 

            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }

}
XXX
  • 273
  • 1
  • 2
  • 9
  • bad news you cannot call .getView() either, what you can do is to call getChildAt but with adjusted index, see .getFirstVisiblePosition – pskink Feb 26 '14 at 07:39