BottomSheetDialog在横屏/折叠屏手机展开大屏时显示不全

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,以下分几种情况讨论。

  1. contentHeight>expandedHeight,BottomSheetDialog弹窗后弹窗高度为peekHeight,上划可达到expandedHeight;
  2. expandedHeight>contentHeight>peekHeight,BottomSheetDialog弹窗后弹窗高度为peekHeight,上划后达到contentHeight,不会到达expandedHeight;
  3. 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在横屏下也能显示正常。

 

参考:

编辑于 2024-11-08 21:33
目录