Android ListView (Scrolling ViewGroup) Hide/Disable Scrollbars

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.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download

Author: Rishabh

Rishabh is a full stack web and mobile developer from India. Follow me on Twitter.

Leave a Reply

Your email address will not be published. Required fields are marked *