如何动态设置Android Support Design BottomSheet的最大展开高度?
如何动态设置Android BottomSheet的最大展开高度?
我之前折腾BottomSheet的时候也踩过这个坑——直接改LayoutParams根本不管用,因为BottomSheet的高度逻辑是由它的Behavior来管控的。下面给你分享两个亲测有效的方法,能根据屏幕尺寸动态设置最大展开高度:
方法一:自定义BottomSheetBehavior(最推荐)
这种方式最灵活,能从根源上控制BottomSheet的高度逻辑,步骤也很清晰:
- 首先创建一个自定义Behavior类,继承官方的
BottomSheetBehavior,添加设置最大高度的方法,并重写布局逻辑 - 在XML布局里指定使用这个自定义Behavior
- 在代码中根据屏幕尺寸计算目标高度,传给自定义Behavior
自定义Behavior代码示例(Kotlin)
class CustomBottomSheetBehavior<V : View>(context: Context, attrs: AttributeSet) : BottomSheetBehavior<V>(context, attrs) { private var maxSheetHeight: Int = 0 // 对外暴露设置最大高度的方法 fun setMaxSheetHeight(height: Int) { maxSheetHeight = height requestLayout() // 触发重新布局 } override fun onLayoutChild(parent: CoordinatorLayout, child: V, layoutDirection: Int): Boolean { // 如果设置了最大高度,就先调整子View的布局参数 if (maxSheetHeight > 0) { val layoutParams = child.layoutParams as CoordinatorLayout.LayoutParams layoutParams.height = maxSheetHeight child.layoutParams = layoutParams } return super.onLayoutChild(parent, child, layoutDirection) } }
布局文件中使用自定义Behavior
<LinearLayout android:id="@+id/bottom_sheet_container" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical" app:layout_behavior="com.your.package.name.CustomBottomSheetBehavior"> <!-- 这里放你的BottomSheet内容,比如RecyclerView、TextView等 --> </LinearLayout>
在Activity/Fragment中动态设置高度
// 获取BottomSheet实例 val bottomSheet = findViewById<LinearLayout>(R.id.bottom_sheet_container) // 获取自定义Behavior val behavior = CustomBottomSheetBehavior.from(bottomSheet) // 计算屏幕高度的80%作为最大展开高度(可根据需求调整比例) val screenHeight = resources.displayMetrics.heightPixels val targetMaxHeight = (screenHeight * 0.8).toInt() // 设置最大高度 behavior.setMaxSheetHeight(targetMaxHeight)
方法二:监听BottomSheet状态动态调整高度(快速实现)
如果不想自定义Behavior,可以通过监听BottomSheet的状态变化,在它展开时动态修改高度:
val bottomSheet = findViewById<LinearLayout>(R.id.bottom_sheet_container) val behavior = BottomSheetBehavior.from(bottomSheet) behavior.addBottomSheetCallback(object : BottomSheetBehavior.BottomSheetCallback() { override fun onStateChanged(bottomSheet: View, newState: Int) { // 当BottomSheet完全展开时,调整高度 if (newState == BottomSheetBehavior.STATE_EXPANDED) { val screenHeight = resources.displayMetrics.heightPixels val maxHeight = (screenHeight * 0.75).toInt() // 比如设置为屏幕高度的75% val layoutParams = bottomSheet.layoutParams layoutParams.height = maxHeight bottomSheet.layoutParams = layoutParams } } override fun onSlide(bottomSheet: View, slideOffset: Float) { // 滑动过程中的回调,不需要可以留空 } })
注意事项
- 如果BottomSheet里是可滚动组件(比如RecyclerView),要确保组件的内容高度不超过设置的最大高度,否则可能出现滚动异常
- 计算屏幕高度时,如果想排除状态栏/导航栏的高度,可以用
activity.window.decorView.rootView.height来获取可用内容高度,而不是直接用屏幕总高度
内容的提问来源于stack exchange,提问作者saurabh dhillon
相关产品推荐
相关产品推荐

