Compose BottomSheet控件的封装,方便维护和调用,不用再去写重复代码了
1.简单,易懂,方便调用,支持Bundle数据传递到BottomSheet内部
MultiBottomSheetLayout(
//bottomSheet顶部边距
sheetModifier = Modifier.padding(top = 46.dp),
sheetShape = 自己定义一个shape,
sheetContent = { bundle ->
//底部弹出来的BottomSheet,根据bundle解析数据渲染
PopBottomScreen(arguments = bundle)
}, mainContent = { openSheet ->
//主界面内容,activityContentView
MainContent(openSheet)
})
2.我们先定义一个密封类MultiBottomSheet
sealed class MultiBottomSheet() {
//支持传入Bundle,通过Bundle去解析数据,渲染新BottomSheet页面内容
class Intent(val arguments:Bundle? = null):MultiBottomSheet()
}
密封类:自身抽象的,它不能直接实例化
kotlin不熟悉的可以去学习以下kotlin,本篇文章仅提供一个封装控件的整个流程讲解
3.Compose中要用BottomSheet,必须要创建一个BottomSheetScaffold脚手架
val bottomSheetScaffoldState = rememberBottomSheetScaffoldState(.....)
BottomSheetScaffold(
sheetContent = {
//想在底部弹出来显示的内容
},
scaffoldState = bottomSheetScaffoldState) {
//显示在屏幕中的内容contentView
}
)
//显示和关闭需要在协程中执行哦
//显示的时候,调用:bottomSheetScaffoldState.bottomSheetState.expand()
//关闭的时候,调用:bottomSheetScaffoldState.bottomSheetState.collapse()
4.开始封装MultiBottomSheetLayout
4.1 函数提取
@SuppressLint("ModifierParameter")
@OptIn(ExperimentalMaterialApi::class)
@Composable
fun MultiBottomSheetLayout(
sheetModifier: Modifier = Modifier,
sheetElevation: Dp = 0.dp,
sheetShape: Shape = MaterialTheme.shapes.large,
mainContent: @Composable (sheetScreen: (MultiBottomSheet.Intent) -> Unit) -> Unit,
sheetContent: @Composable (arguments: Bundle?) -> Unit,
topLeftIcon: (@Composable (onClosePressed: () -> Unit) -> Unit)? = null,
topCenterIcon: (@Composable (onClosePressed: () -> Unit) -> Unit)? = null,
topRightIcon: (@Composable (onClosePressed: () -> Unit) -> Unit)? = null
){.....}
4.2 记录状态,处理开关动作
val scope = rememberCoroutineScope()
val scaffoldState = rememberBottomSheetScaffoldState()
//记录BottomSheet
var currentBottomSheet: MultiBottomSheet.Intent? by remember{
mutableStateOf(null)
}
//关闭的时候需要置空
if(scaffoldState.bottomSheetState.isCollapsed){
currentBottomSheet = null
}
//执行关闭BottomSheet
val closeSheet: () -> Unit = {
scope.launch {
scaffoldState.bottomSheetState.collapse()
}
}
//展开BottomSheet
val openSheet: (MultiBottomSheet.Intent) -> Unit = {
scope.launch {
currentBottomSheet = it
scaffoldState.bottomSheetState.expand()
}
}
4.3 状态和数据传入BottomSheetScaffold
BottomSheetScaffold(sheetPeekHeight = 0.dp, scaffoldState = scaffoldState,
sheetElevation = sheetElevation,
sheetShape = sheetShape,
// 来设置BottomSheet弹出来的视图【距离】『屏幕顶部的距离』
modifier = sheetModifier,
sheetContent = {
//显示弹出来的视图....
}) { paddingValues ->
Box(Modifier.padding(paddingValues)){
//activityContentView
mainContent(openSheet)
}
}
5.BottomSheetLayout支持外部传入topLeft,topCenter,topRight 顶部IconButton
这里我们需要把4.3里面的sheetContent = {....} 再提取一下,提炼出一个BottomSheetWithTopClose方法
@Composable
private fun BottomSheetWithTopClose(.....){
Box(modifier.fillMaxWidth()) {
content()
if(topLeftIcon != null){
IconButton(){
topLeftIcon()
}
}
//.......
}
}
6.如果看了上面,👇👇不会封装的可以看一下我们封装好的代码:
里面有测试代码,有需要的,可以参考一下