ListView scrolling inside BottomSheet

I’m working on a personal project that uses a ListView inside the new widget BottomSheet and I found one issue. When the BottomSheet is expanded and the ListView is totally visible, you can scroll down, but when you try to scroll up, you drag the BottomSheet instead of the ListView.

I worte one class that extends the original ListView and solves this. It scrolls the ListView by default, but has two ways to determine if should scroll the BottoomSheet instead of the ListView.

  1. If the ListView are on top.
  2. If the first and the last items of the ListView are visible (no scroll available).

And, with no more delay, the class:

package com.your.app;

import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.widget.AbsListView;
import android.widget.ListView;

/**
 * Created by emmgfx on 26/3/16.
 */

public class BottomSheetListView extends ListView {

    public BottomSheetListView(Context p_context, AttributeSet p_attrs){
        super(p_context, p_attrs);
    }

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

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

    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 && getLastVisiblePosition() == view.getChildCount();

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

        return canScroll;
    }

}

And the instantiation in the Activity.

// ...
private BottomSheetListView lvSlotResults;
// ...
lvSlotResults = (BottomSheetListView) findViewById(R.id.lvSlotResults);

Of course, I wrote this by merging multiple solutions from Stackoverflow. Basically this and this. Thanks.

Comentarios (2)

return false 

 @Override
    public boolean onInterceptTouchEvent(MotionEvent p_event){
        return false;
    }

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.