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 m
I have tried Nested ListViews that was described here, but they do not allow expand /collapse bottom sheet when touching on ListView
. Below is my solution, when you scroll up and ListView
cannot scroll up, bottom sheet will be expanded, when you scroll down and ListView
cannot do it, BottomSheet
will be collapsed.
public class NestedListView extends ListView {
private boolean mIsBeingDragged = false;
private float mLastMotionY;
public NestedListView(final Context context, final AttributeSet attrs) {
super(context, attrs);
}
public NestedListView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
public boolean onInterceptTouchEvent(MotionEvent event) {
switch (event.getActionMasked()) {
case MotionEvent.ACTION_DOWN: {
if (canScrollDown() || canScrollUp()) {
final ViewParent parent = getParent();
if (parent != null) {
parent.requestDisallowInterceptTouchEvent(true);
}
}
break;
}
}
return super.onInterceptTouchEvent(event);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
final float y = event.getRawY();
switch (event.getActionMasked()) {
case MotionEvent.ACTION_MOVE: {
if (!mIsBeingDragged) {
final float deltaY = mLastMotionY - y;
mIsBeingDragged = (deltaY > 0 && canScrollDown())
|| (deltaY < 0 && canScrollUp());
if (mIsBeingDragged) {
final ViewParent parent = getParent();
if (parent != null) {
parent.requestDisallowInterceptTouchEvent(true);
}
} else {
final ViewParent parent = getParent();
if (parent != null) {
parent.requestDisallowInterceptTouchEvent(false);
}
return false;
}
}
}
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
mIsBeingDragged = false;
break;
}
mLastMotionY = y;
return super.onTouchEvent(event);
}
public boolean canScrollUp() {
final int childCount = getChildCount();
if (childCount == 0) {
return false;
}
final int firstPosition = getFirstVisiblePosition();
final int firstTop = getChildAt(0).getTop();
return firstPosition > 0 || firstTop < getListPaddingTop();
}
public boolean canScrollDown() {
final int childCount = getChildCount();
if (childCount == 0) {
return false;
}
final int firstPosition = getFirstVisiblePosition();
final int lastBottom = getChildAt(childCount - 1).getBottom();
final int lastPosition = firstPosition + childCount;
return lastPosition < getCount() || lastBottom > getHeight() - getListPaddingBottom();
}
}
Starting from version 22.1.0, you might want to try setNestedScrollingEnabled=true
If this property is set to true the view will be permitted to initiate nested scrolling operations with a compatible parent view in the current hierarchy. If this view does not implement nested scrolling this will have no effect. Disabling nested scrolling while a nested scroll is in progress has the effect of stopping the nested scroll.
Reference to Google API