我有一个底部工作表嵌套在另一个底部工作表中FrameLayouts
使用BottomSheet
布局行为)
我还有一些附加点击监听器的“窥视视图”(FrameLayouts
),在点击时分别展开底部工作表。
因此该应用程序基本上有3个主屏幕。 “主容器”,然后是第一个“底部薄片”,可以全屏展开,然后在第一个底部薄片的底部,是第二个底部薄片,也可以全屏展开。
问题:
当我将RecyclerView
添加到嵌套的底部“容器”视图时,拖动停止为第二个窥视视图工作(Sheet 2 Peek)。如果我删除查看视图ClickListener
或 RecyclerView
,那么事情似乎完全正常。
期望的结果:
两个底部工作表都应保持可拖动状态,并且应该可以单击窥视视图以展开其父底部工作表。底部工作表应该像通常那样响应嵌套的滚动。
我尝试删除ClickListener
并使用触摸手势,但我尝试的任何内容似乎都没有帮助。
我正在使用v25.3.1
设计支持库,我能够在运行4.4.4库存的Galaxy S4和运行7.1.2库存的Nexus 6P上重现此问题。 (我没有任何其他设备可用)。
我还在github上为有兴趣仔细研究的人创建了一个测试项目: https://github.com/timusus/bottomsheet-test
以下是一些展示布局的屏幕截图:
布局结构如下所示(为清晰起见,省略了一些代码):
<CoordinatorLayout>
<FrameLayout
android:id="@+id/mainContainer"
android:layout_height="match_parent"/>
<FrameLayout
android:id="@+id/sheet1"
android:layout_height="match_parent"
app:layout_behavior="CustomBottomSheetBehavior"
app:behavior_peekHeight="64dp">
<FrameLayout
android:id="@+id/sheet1Container"
android:layout_height="match_parent"/>
<CoordinatorLayout>
<FrameLayout
android:id="@+id/sheet2
android:layout_height="match_parent"
app:layout_behavior="CustomBottomSheetBehavior"
app:behavior_peekHeight="64dp">
<FrameLayout
android:id="@+id/sheet2Container"
android:layout_height="match_parent">
<!-- Problematic RecyclerView -->
<RecyclerView
android:layout_height="match_parent"/>
</FrameLayout>
<!-- Problematic Click Listener on this view -->
<FrameLayout
android:id="@+id/sheet2PeekView"
android:layout_height=64dp"/>
</FrameLayout>
</CoordinatorLayout>
<FrameLayout
android:id="@+id/sheet1PeekView"
android:layout_height=64dp"/>
</FrameLayout>
</CoordinatorLayout/>
CustomBottomSheetBehavior
只是BottomSheetBehavior
的一个简单子类,可以防止第一张图片在第二张图片展开或拖动时拦截触摸事件。这样可以将第二张纸从“展开”拖动到“折叠”,而不会折叠第一张纸。
public class CustomBottomSheetBehavior<V extends View> extends BottomSheetBehavior<V> {
private boolean allowDragging = true;
public void setAllowDragging(boolean allowDragging) {
this.allowDragging = allowDragging;
}
@Override
public boolean onInterceptTouchEvent(CoordinatorLayout parent, V child, MotionEvent event) {
if (!allowDragging) {
return false;
}
return super.onInterceptTouchEvent(parent, child, event);
}
}
我不相信BottomSheetBehavior
的自定义与此问题相关,但为了完整性,以下是它的使用方法:
FrameLayout sheet1 = (FrameLayout) findViewById(R.id.sheet1);
bottomSheetBehavior1 = (CustomBottomSheetBehavior) BottomSheetBehavior.from(sheet1);
FrameLayout sheet2 = (FrameLayout) findViewById(R.id.sheet2);
bottomSheetBehavior2 = (CustomBottomSheetBehavior) BottomSheetBehavior.from(sheet2);
bottomSheetBehavior2.setBottomSheetCallback(new BottomSheetBehavior.BottomSheetCallback() {
@Override
public void onStateChanged(@NonNull View bottomSheet, int newState) {
//If the second sheet is expanded or dragging, don't allow the first sheet to respond to touch events.
if (newState == BottomSheetBehavior.STATE_EXPANDED || newState == BottomSheetBehavior.STATE_DRAGGING) {
bottomSheetBehavior1.setAllowDragging(false);
} else {
bottomSheetBehavior1.setAllowDragging(true);
}
}
我似乎无法弄清楚这是否与onInterceptTouchEvent
的{{1}}有关,内部BottomSheet
,RecyclerView
偷窃触摸的嵌套滚动处理事件,上述事物的组合或其他事物。
非常感谢任何帮助。
答案 0 :(得分:13)
<强>固定强>
我似乎无法弄清楚这是否与此有关 BottomSheet的onInterceptTouchEvent,嵌套滚动处理 内部RecyclerView,View.ClickListener窃取触摸事件,a 以上的组合,或其他一切。
它是以上 CustomBottomSheetBehavior 和 View.ClickListener
的组合问题 bottomSheetBehavior1 正在拖动 getSheet2PeekView 时执行拖动事件,因此检测 getSheet2PeekView 上的触摸事件并设置 bottomSheetBehavior1 拖动false
和 bottomSheetBehavior2 true
输入此代码,您的问题就解决了。
findViewById(getSheet2PeekViewResId()).setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
Log.e(TAG, "onTouch: ");
bottomSheetBehavior1.setAllowDragging(false);
bottomSheetBehavior2.setAllowDragging(true);
return false;
}
});
还为您的回购邮件创建了 Pull Request ,并进行了全面的更改。