ListView in BottomSheet

ᴛʜᴇᴘᴀᴛᴇʟ picture ᴛʜᴇᴘᴀᴛᴇʟ · Nov 13, 2016 · Viewed 14.9k times · Source

I ran into a problem where I had a simple ListView in a BottomSheet and ListView had enough items to fill the screen and scroll even more.

When I scroll down, everything seems to work however when I tried to scroll back up, it was scrolling the BottomSheet itself and closing the view instead of just scrolling the ListView.

I was able to find a solution after a while and since I couldn't find it anywhere here, I figured I would post it here.

Answer

ᴛʜᴇᴘᴀᴛᴇʟ picture ᴛʜᴇᴘᴀᴛᴇʟ · Nov 13, 2016

The solution is to extend the ListView like this:

public class BottomSheetListView extends ListView {
    public BottomSheetListView (Context context, AttributeSet p_attrs) {
        super (context, p_attrs);
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        return true;
    }

    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        if (canScrollVertically(this)) {
            getParent().requestDisallowInterceptTouchEvent(true);
        }
        return super.onTouchEvent(ev);
    }

    public boolean canScrollVertically (AbsListView view) {
        boolean canScroll = false;

        if (view !=null && view.getChildCount ()> 0) {
            boolean isOnTop = view.getFirstVisiblePosition() != 0 || view.getChildAt(0).getTop() != 0;
            boolean isAllItemsVisible = isOnTop && view.getLastVisiblePosition() == view.getChildCount();

            if (isOnTop || isAllItemsVisible) {
                canScroll = true;
            }
        }

        return  canScroll;
    }
}

Then in your layout file bottom_sheet_view.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <com.mypackage.name.BottomSheetListView
        android:id="@+id/listViewBtmSheet"
        android:divider="@color/colorPrimary"
        android:dividerHeight="1dp"
        android:layout_weight="1"
        android:layout_width="match_parent"
        android:layout_height="0dp" />

</LinearLayout>

Then finally, in your Activity/Fragment:

BottomSheetDialog dialog = new BottomSheetDialog(context);
dialog.setContentView(R.layout.bottom_sheet_view);

BottomSheetListView listView = (BottomSheetListView) dialog.findViewById(R.id.listViewBtmSheet);
// apply some adapter - add some data to listview

dialog.show();

This will provide a BottomSheet that is fully working with ListView scroll.