How to prevent ListView from scrolling when touching / scrolling / deleting by line?

I need to stop the ListView in order to respond to user gestures if these gestures are made on a specific ListView line - How to do this? There is an onTouchListener set in the Target ListView row view, and I cannot recognize swipe / flip due to Scrolling ListView up / down. Therefore, if I move my finger up or down a bit, the ListView intercepts this and scrolls in the appropriate direction. Therefore, I need to somehow manage this, as if Y-coordinated more than some part - let the ListView scroll, and if not - recognize the gesture as fling / swipe. OnTouchListener -

private int SWIPE_MIN_DISTANCE = 1; private int SWIPE_MAX_OFF_PATH = 300; final OnTouchListener flingSwipeListener = new OnTouchListener() { float touchX; float touchY; @Override public boolean onTouch(final View view, final MotionEvent event) { if (event.getAction() == MotionEvent.ACTION_DOWN) { touchX = event.getX(); touchY = event.getY(); } else if (event.getAction() == MotionEvent.ACTION_UP) { if (Math.abs(touchY - event.getY()) > SWIPE_MAX_OFF_PATH) return false; // right to left swipe else if (touchX - event.getX() > SWIPE_MIN_DISTANCE){ Log.i("flingSwipe","right to left swipe"); } // left to right swipe else if (event.getX() - touchX > SWIPE_MIN_DISTANCE){ Log.i("flingSwipe","left to right swipe"); } } return true; } }; 

This onTouchListner has been set to one specific line. I need to freeze the ListView while onTouchListener recognizes the gesture, but if it fails, I need to send a MotionEvent to the ListView.

+4
source share
2 answers

If you want to disable vertical scrolling of a ListView when any horizontal scrolling (scrolling) is detected, use the following solution - override onTouchEvent in your custom ListView class and replace the MotionEvent.ACTION_MOVE action with MotionEvent.ACTION_CANCEL:

 public class ListView2 extends ListView { private enum ScrollDirection { Horizontal, Vertical } private final int touchSlop; private float downX = 0; private float downY = 0; private ScrollDirection scrollDirection; public ListView2(Context context, AttributeSet attrs) { super(context, attrs); touchSlop = ViewConfiguration.get(context).getScaledTouchSlop(); } @Override public boolean onTouchEvent(MotionEvent ev) { switch (ev.getActionMasked()) { case MotionEvent.ACTION_MOVE: if (scrollDirection == null) { if (Math.abs(downX - ev.getX()) > touchSlop) scrollDirection = ScrollDirection.Horizontal; else if (Math.abs(downY - ev.getY()) > touchSlop) scrollDirection = ScrollDirection.Vertical; } if (scrollDirection == ScrollDirection.Horizontal) ev.setAction(MotionEvent.ACTION_CANCEL); break; case MotionEvent.ACTION_DOWN: scrollDirection = null; downX = ev.getX(); downY = ev.getY(); break; } return super.onTouchEvent(ev); } } 

Of course, you can make the logic of checking whether to disable vertical scrolling more complex.

+1
source

if you need to disable the touch listener on a specific line. than it is simple.

set the tag to the desired line of the list. in the list view adapter class.

eg:

 ABCList extends ArrayAdapter<String> { public MyCustomAdapter(Context context, int textViewResourceId, String[] objects) { super(context, textViewResourceId, objects); } @Override public View getView(int position, View convertView, ViewGroup parent) { View row = inflater.inflate(R.layout.history_list_item, parent, false); if(position == YOUR_DESIRED_ROW) row.setTag("disableThisRow") return row; } } 

then edit the touch listener as follows.

  final OnTouchListener flingSwipeListener = new OnTouchListener() { float touchX; float touchY; @Override public boolean onTouch(final View view, final MotionEvent event) { String isRow=view.getTag(); if(isRow.equals("disableThisRow"))return false; if (event.getAction() == MotionEvent.ACTION_DOWN) { touchX = event.getX(); touchY = event.getY(); } else if (event.getAction() == MotionEvent.ACTION_UP) { if (Math.abs(touchY - event.getY()) > SWIPE_MAX_OFF_PATH) return false; // right to left swipe else if (touchX - event.getX() > SWIPE_MIN_DISTANCE){ Log.i("flingSwipe","right to left swipe"); } // left to right swipe else if (event.getX() - touchX > SWIPE_MIN_DISTANCE){ Log.i("flingSwipe","left to right swipe"); } } return true; } }; 

this will disable touching the list item tirelessly. hope this helps. or if you are more gesture listeners than it will also be like this. hope this helps

0
source

Source: https://habr.com/ru/post/1490586/


All Articles