1 问题背景
公司APP的某个需求的底部弹窗使用了Android Material Design库的BottomSheetDialog组件实现。由于公司要求在折叠屏手机展开大屏时APP能正常使用,在某次冒烟自测时使用了折叠屏手机做测试,发现该底部弹窗显示不全,影响正常功能使用,需要修复。
此处使用模拟器强制APP横屏来模拟折叠屏手机展开大屏时的显示效果。
可以看到,底部的弹窗只弹出了一点点,下方的功能按键显示不全,影响了正常的使用,需要及时整改。
2 解决方案
在style文件中,设置behavior_peekHeight为超过底部弹窗设计高度的数值即可。
3 原理分析
BottomSheetDialog继承于AppCompatDialog,本质上是一个普通的Dialog,其底部弹窗的行为、交互通过BottomSheetDialog进行控制。BottomSheetDialog的官方定义如下:
An interaction behavior plugin for a child view of CoordinatorLayout to make it work as a bottom sheet.
一个使CoordinatorLayout中的子View具有底部弹窗交互行为的插件。
对于BottomSheetDialog来说,其高度通过BottomSheetBehavior进行控制,主要有expandedHeight和peekHeight两个参数。其中expandedHeight为BottomSheetDialog最大上划显示高度,peekHeight为BottomSheetDialog首次弹出时的最大显示高度。
假设BottomSheetDialog弹窗中内容的高度为contentHeight,以下分几种情况讨论。
- contentHeight>expandedHeight,BottomSheetDialog弹窗后弹窗高度为peekHeight,上划可达到expandedHeight;
- expandedHeight>contentHeight>peekHeight,BottomSheetDialog弹窗后弹窗高度为peekHeight,上划后达到contentHeight,不会到达expandedHeight;
- peekHeight>contentHeight,BottomSheetDialog弹窗后弹窗高度为contentHeight,上划无效。
查看BottomSheetBehavior的原码,当bottomSheetStyleWrapper中没有设置behavior_peekHeight时,peekHeightAuto为true,取peekHeightMin和parentHeight - parentWidth * 9 / 16中的最大值。peekHeightMin的值固定为64dp,保证BottomSheetDialog的最小弹出高度为64dp;parentHeight - parentWidth * 9 / 16在竖屏模式下,大约为屏幕高度60%的值。
在横屏模式下,parentHeight<parentWidth,parentHeight - parentWidth * 9 / 16为负数,因此lastPeekHeight取peekHeightMin,最终BottomSheetDialog的高度为peekHeightMin,导致BottomSheetDialog首次弹出的高度非常低,内容显示不全,需要上划才能显示完全。
因此,在bottomSheetStyleWrapper中设置behavior_peekHeight的值为超过底部弹窗设计高度(contentHeight)的数值,可保证BottomSheetDialog在横屏下也能显示正常。
参考: