📜 ⬆️ ⬇️

Stop scrollview scrolling

There was a need to make Drag'n'Drop from the ScrollView element.
And to solve this problem without using extraneous libraries and for all devices, starting with Froyo.
The process of dragging an item is not a problem.
The problem is to disable the list scrolling after we are no longer working with it.

The fact is that after we dragged an element out of the ScrollView and moved it to the right place, ScrollView continues to monitor our movements and continues to scroll. This does not affect the functionality, but is unacceptable in terms of interface design.
The topic is quite simple. I think almost every programmer is able to solve this problem on his own.
But the problem is that instead of inventing a bicycle, we often climb into the Internet in search of a solution.
And we find. Including stackoverflow offers us a completely “working” solution.
I would not be surprised that someone can apply it in their code without careful checking ...
The solution is this:
dispatchTouchEvent(MotionEvent.obtain(SystemClock.uptimeMillis(), SystemClock.uptimeMillis(), MotionEvent.ACTION_CANCEL, 0, 0, 0)); 


At first glance - an adequate solution. And it works! That's just it breaks touch processing in ScrollView. The result is an application crash with stack overflow at an unpredictable point in time.
The solution looks beautiful, but you can't use it! And the point here is not only that events should be freed after creation.

There is a slightly more sophisticated solution, but much safer and more predictable.
It is necessary to expand the functionality of ScrollView as follows:
 public class ScrollViewEx extends ScrollView { protected boolean scrollActive = true; public ScrollViewEx(Context context) { super(context); } public ScrollViewEx(Context context, AttributeSet attrs){ super(context,attrs); } public ScrollViewEx(Context context, AttributeSet attrs, int defStyle){ super(context,attrs,defStyle); } public void stopScroll(){ scrollActive = false; } @Override public boolean dispatchTouchEvent(MotionEvent event){ if (event.getAction()==MotionEvent.ACTION_DOWN) scrollActive = true; if (scrollActive || event.getAction()!=MotionEvent.ACTION_MOVE) return super.dispatchTouchEvent(event); return false; } } 

')
Here a very simple thing is done - a variable is created that is responsible for disabling the scroll.
The variable is set by the programmer at the right time and automatically reset when the item is clicked.
All that the variable does is block the widget's handling of a “touch move” event.
Accordingly, we call the stopScroll method at the right moment, after which the list continues processing touch messages, but does not respond to movement. No scrolling occurs.
If the user again clicked on the list, then scrolling is turned back on.
Problem solved. At the same time, the code is much more predictable and correct.

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


All Articles