当我们使用CoordinatorLayout中的 BottomSheetBehavior 抽屉式布局时, 快速滑动RecyclerView或者NestedScrollView 时,会触发BottomSheetBehavior 的STATE_COLLAPSED 动作,导致抽屉布局被异常关闭,效果很差。
解决:
查看BottomSheetBehavior 源码发现,使抽屉布局关闭的是如下代码
@Override
public void onNestedPreScroll(
@NonNull CoordinatorLayout coordinatorLayout,
@NonNull V child,
@NonNull View target,
int dx,
int dy,
@NonNull int[] consumed,
int type) {
if (type == ViewCompat.TYPE_NON_TOUCH) {
// Ignore fling here. The ViewDragHelper handles it.
return;
}
View scrollingChild = nestedScrollingChildRef != null ? nestedScrollingChildRef.get() : null;
if (target != scrollingChild) {
return;
}
int currentTop = child.getTop();
int newTop = currentTop - dy;
if (dy > 0) { // Upward
if (newTop < getExpandedOffset()) {
consumed[1] = currentTop - getExpandedOffset();
ViewCompat.offsetTopAndBottom(child, -consumed[1]);
setStateInternal(STATE_EXPANDED);
} else {
if (!draggable) {
// Prevent dragging
return;
}
consumed[1] = dy;
ViewCompat.offsetTopAndBottom(child, -dy);
setStateInternal(STATE_DRAGGING);
}
} else if (dy < 0) { // Downward
if (!target.canScrollVertically(-1)) {
if (newTop <= collapsedOffset || hideable) {
if (!draggable) {
// Prevent dragging
return;
}
consumed[1] = dy;
ViewCompat.offsetTopAndBottom(child, -dy);
setStateInternal(STATE_DRAGGING);
} else {
consumed[1] = currentTop - collapsedOffset;
ViewCompat.offsetTopAndBottom(child, -consumed[1]);
setStateInternal(STATE_COLLAPSED);
}
}
}
dispatchOnSlide(child.getTop());
lastNestedScrollDy = dy;
nestedScrolled = true;
}
从源码发现,BottomSheetBehavior 的滚动是根据自身状态和是否触摸来判断的,如果想加入可控性,
只需要在代码前加上
if (!draggable){
return;
}
即可