我的应用布局包含自定义toolbar
和持久性BottomSheet
- 都位于CoordinatorLayout
内。
点击按钮我想显示BottomSheet
。现在,工作表全屏显示并覆盖toolbar
。通过将应用主题设置为Theme.AppCompat.Light.DarkActionBar
BottomSheet
保持在ActionBar
以下,但该栏无法自定义。
有没有办法将持久性BottomSheet
的高度限制为全屏 - ActionBar
高度?
这是我在activity_main.xml
<android.support.design.widget.CoordinatorLayout
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:attrs="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.test.MainActivity">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
app:elevation="20dp"
android:elevation="20dp"
android:layout_height="?attr/actionBarSize">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
app:elevation="20dp"
android:elevation="20dp"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"/>
</android.support.design.widget.AppBarLayout>
</LinearLayout>
<include layout="@layout/bottom_sheet_additem"/>
</CoordinatorLayout>
以下是sheet_bottom.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/bottomSheetLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/colorAccent"
app:behavior_hideable="true"
app:behavior_peekHeight="0dp"
android:fitsSystemWindows="true"
app:layout_behavior="@string/bottom_sheet_behavior">
<TextView
android:id="@+id/bottomsheet_text"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:text="Lorem Ipsum Dolor..."
android:textColor="#FFFFFF" />
</RelativeLayout>
答案 0 :(得分:15)
我遇到了同样的问题。
尝试将您的包含在activity_main.xml
中的另一个CoordinatorLayout中,并使用marginTop:
<android.support.design.widget.CoordinatorLayout
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:attrs="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.test.MainActivity">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
app:elevation="20dp"
android:elevation="20dp"
android:layout_height="?attr/actionBarSize">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
app:elevation="20dp"
android:elevation="20dp"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"/>
</android.support.design.widget.AppBarLayout>
</LinearLayout>
<android.support.design.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="56dp">
<include layout="@layout/bottom_sheet_additem"/>
</android.support.design.widget.CoordinatorLayout>
</CoordinatorLayout>
让我知道它是否适合你。
答案 1 :(得分:1)
我们可以使用app:layout_behavior而不是固定高度
<android.support.design.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<include layout="@layout/bottom_sheet_additem"/>
</android.support.design.widget.CoordinatorLayout>
答案 2 :(得分:1)
当您将底页扩展到全屏时,可接受的答案有效,但是在折叠时,它会添加额外的边距,从而使部分折叠布局隐藏在屏幕下方,因此我决定通过编程来设置边距,方法是听变为BottomSheet
的折叠/隐藏状态。
首先在xml中的BottomSheet
中添加CoordintorLayout
并在回调监听器下方添加。
mBottomSheetBehavior.addBottomSheetCallback(new BottomSheetBehavior.BottomSheetCallback() {
@Override
public void onStateChanged(@NonNull View bottomSheet, int newState) {
CoordinatorLayout bottomSheet = findViewById(..); // inflate the bottom sheet
CoordinatorLayout.LayoutParams layoutParams =
(CoordinatorLayout.LayoutParams) bottomSheet.getLayoutParams();
if (newState == BottomSheetBehavior.STATE_COLLAPSED)
layoutParams.setMargins(0, 0, 0, 0); // remove top margin
else if (newState == BottomSheetBehavior.STATE_EXPANDED) {
layoutParams.setMargins(0, 100, 0, 0); // add top margin
bottomSheet.setLayoutParams(layoutParams);
}
@Override
public void onSlide(@NonNull View bottomSheet, float slideOffset) {
}
});
答案 3 :(得分:0)
您的sheet_bottom应该看起来像这样
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
tools:showIn="@layout/activity_main">
<RelativeLayout
android:id="@+id/bottom_sheet"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:behavior_hideable="true"
app:behavior_peekHeight="?android:attr/actionBarSize"
app:elevation="@dimen/size_5dp"
app:layout_behavior="@string/bottom_sheet_behavior">
</RelativeLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
答案 4 :(得分:0)
+1 用于以编程方式更新边距。虽然可以通过增加查看高度来抵消 BottomSheet 的隐藏部分,但仅使用上面的原始解决方案意味着边距会投射到底层 UI 元素上,因此滚动操作区域会从实际的 BottomSheet 投射到其他 UI 上。
在BottomSheetCallback 中使用onStateChanged 方法意味着对BottomSheet 已经展开或折叠的事件进行操作。在此阶段添加或删除边距可能会导致看到“抖动”行为,例如,在以编程方式应用边距以将 UI 组件向下移动导致“闪烁”之前,工作表会暂时达到覆盖应用栏的完全展开状态这适用。
相反,我使用 onSlide 方法来检测 BottomSheet 何时向上或向下滑动,并仅在纸张过渡到一半时添加或删除边距。如果在滑动动作中过早地应用了边距,那么用户可以在启动动作后不久再次看到BottomSheet UI 向上或向下跳跃(如果他们已经完成了“fling”,他们不太可能在中途注意到这一点) ' 向上或向下运动。
我还发现获取 AppBar 和状态栏的高度并使用它们来设置所需的填充值以在展开模式下准确放置效果最好。
通过使用小部件以编程方式触发 BottomSheet 状态更改,可以完全避免此挑战。
@Override
public void onSlide(View bottomSheet, float slideOffset) {
boolean inRangeExpanding = oldOffSet < slideOffset;
boolean inRangeCollapsing = oldOffSet > slideOffset;
oldOffSet = slideOffset;
if (inRangeCollapsing && slideOffset < 0.5f) {
//reset padding on top of bottomsheet so there is no padding/overlap onto underlying sheet (which overlaps underlying sheet and so interfers with scrolling behaviour
bSheetView.setPadding(0,10,0,0);
Log.d(TAG,"onSlide STATE_COLLAPSING");
} else if(inRangeExpanding && slideOffset > 0.5f){
//reset padding on top of bottomsheet so there is padding/overlap onto underlying sheet so it does not write over the top of the menu appbar
bSheetView.setPadding(0, topMargin,0,0);
Log.d(TAG,"onSlide STATE_EXPANDING");
}
}