In Android, if you’ve ever wanted to sort of disable the scrollbars of a scrolling ViewGroup like a ListView, GridView, ScrollView, etc. then there are a few tricks to do that. I’ve tried to compile a set of such tricks to disable (or just hide) scrollbars for such scrolling View Groups.
XML Layout
android:scrollbars="none"
android:scrollbars
will define which scrollbars to display or show any at all. This won’t disable scrolling as such (you’ll be able to scroll in the appropriate direction) but just hide the scrollbars from the user interface. More of a UI switch.
What's the one thing every developer wants? More screens! Enhance your coding experience with an external monitor to increase screen real estate.
Programatically, you can call View.setVerticalScrollBarEnabled(boolean)
and View.setHorizontalScrollBarEnabled(boolean)
for similar effect.
Return true from ListView onTouch event
listView.setOnTouchListener(new View.OnTouchListener() { public boolean onTouch(View v, MotionEvent event) { return (event.getAction() == MotionEvent.ACTION_MOVE); } });
By returning true
while ACTION_MOVE
move events are generated and dispatched in your custom OnTouchListener
you’re making sure that all the ensuing move events are also sent to this custom listener that has no logic for scrolling. Hence scrolling will get disabled.
More on the Android touch input event system/framework here.
Messing with dispatchTouchEvent()
Let’s say you’re using a custom ListView then you could modify the dispatchTouchEvent()
like this:
public class CustomListView extends ListView { public CustomListView(Context context) { super(context); } public CustomListView(Context context, AttributeSet attrs) { super(context, attrs); } public CustomListView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } @Override public boolean dispatchTouchEvent(MotionEvent ev) { if (ev.getAction() == MotionEvent.ACTION_MOVE) return true; return super.dispatchTouchEvent(ev); } }
What this does is as soon as the user tries to move is finger (scroll/fling/drag on the screen), dispatchTouchEvent()
returns true
which causes it to consume the event (hence none of the children will be allowed to mess with it) and since the super.dispatchTouchEvent()
is not called then, the scrolling algorithm coded in the framework’s ListView is not executed which causes it to prevent scrolling. This is sort of conceptually similar to the previous section.
Instead of modifying the framework’s ViewGroups you could also just do this in the Activity:
@Override public boolean dispatchTouchEvent(MotionEvent ev) { if (ev.getAction() == MotionEvent.ACTION_MOVE) { ev.setAction(MotionEvent.ACTION_CANCEL); } return super.dispatchTouchEvent(ev); }
At an Activity’s level you can use this approach to disable touch events being processed or even route the incoming events to some other touchevent processor of your own.
Here’s an excellent SO thread explaining dispatchTouchEvent(). You should also read the android documentation on input events and one of my previous articles on Android’s touch events framework.
All that said, you might want to just use LinearLayout instead of hiding ListView scrollbars.