Jetpack Compose系列:实现底部弹窗的ModalBottomSheet

在Android中,底部弹窗的使用非常普遍,如微信的更多操作弹窗,网易云音乐的播放列表弹窗等。在传统的View体系里面,我们使用PopupWindow或BottomSheetDialog来实现。而在Jetpack Compose里,官方也提供了一种开箱即用的组件,那就是ModalBottomSheet,由Material 3 Compose库提供。

微信:更多操作底部弹窗

1  基本使用

1.1  添加依赖

dependencies {
   implementation("androidx.compose.material3:material3:newest_version")
}

1.2  在Compose中使用

ModalBottomSheet(onDismissRequest = { /*TODO*/ }) {
  YourComponent()
}

简单的两步,就已经把ModalBottomSheet集成在你的Compose代码中,至于ModalBottomSheet弹窗中的内容有多复杂,就取决于自己了。

ModalBottomSheet还可以传入很多参数,简单列举几个:

参数 作用
sheetState ModalBottomSheet的状态
shape ModalBottomSheet的形状
containerColor ModalBottomSheet的背景颜色
dragHandle ModalBottomSheet顶部拖拽指示器的样式与行为

ModalBottomSheet的这些参数都有默认值(除了onDismissRequest),若不需要改变样式,不需要改变拖拽行为,完全可以不理会这些参数,真的就是开箱即用。

ModalBottomSheet效果图

2  ModalBottomSheet的高度问题

2.1  ModalBottomSheet的状态

ModalBottomSheet有三种状态:

Hidden:ModalBottomSheet完全不可见

Expanded:ModalBottomSheet完全展开

PartiallyExpanded:ModalBottomSheet部分展开

当ModalBottomSheet中的内容高度超过ModalBottomSheet的默认Peek Height(直译为窥视高度?)时(56dp),打开ModalBottomSheet将直接进入PartiallyExpanded状态,只显示部分内容,需要手动往上拖拽ModalBottomSheet转换为Expanded状态,才能显示完全的高度与内容。

以卧卷APP为例,当ModalBottomSheet为PartiallyExpanded状态时,评论弹窗的Emoji面板底部的分页指示器未能显示出来,需要手动向上拖拽ModalBottomSheet转换为Expanded状态,才能把分页显示器也显示出来。

2.2  直接进入Expanded状态的方案

如果我想一打开ModalBottomSheet就是Expanded状态呢?理论上ModalBottomSheet的SheetState有三个方法,分别对应三种状态:

expand( ):转换为Expanded状态

partialExpand( ):转换为PartiallyExpanded状态

hide( ):转换为Hidden状态

亲测ComposeBom版本为2024.05.00的ModalBottomSheet中,手动调用expand( )方法并不能把ModalBottomSheet转换为Expanded状态。

Stack Overflow上的大神们提供了一个解决方案:

val modalBottomSheetState = rememberModalBottomSheetState(
  skipPartiallyExpanded = true
)

ModalBottomSheet(
  onDismissRequest = {/*TODO*/},
  sheetState = modalBottomSheetState
) {
  YourComponent( )
}

skipPartiallyExpanded:如果设置为true,则ModalBottomSheet永远只在Expanded和Hidden状态之间切换

看到这里,ModalBottomSheet在基本使用上应该没什么问题了。🤣

 

参考:

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