跳转到内容

Scaffold

Scaffold 是 Miuix 中的脚手架组件,用于实现基本设计视觉布局结构。它提供了应用程序界面的基本框架,包括顶部栏、底部栏、悬浮按钮等元素的容器。

注意

Scaffold 组件为跨平台提供了一个合适的弹出窗口的容器。SuperDialogSuperDropdownSuperSpinnerListPopup 等组件都基于此实现弹出窗口,因此都需要被该组件包裹。

信息

为什么不用官方的 PopupDialog 而选择自行创建弹出窗口的容器?因为它们目前在跨平台支持中实现不完整,有些参数无法更改。

引入

kotlin
import top.yukonga.miuix.kmp.basic.Scaffold

基本用法

Scaffold 组件可以构建带有顶部栏的页面布局:

kotlin
Scaffold(
    topBar = {
        SmallTopAppBar(title = "标题" )
    },
    content = { paddingValues ->
        // 内容区域需要考虑 padding
        Box(
            modifier = Modifier
                .padding(top = paddingValues.calculateTopPadding(), start = 26.dp)
                .fillMaxSize()
        ) {
            Text("内容区域")
        }
    }
)

属性

Scaffold 属性

属性名类型说明默认值是否必须
modifierModifier应用于脚手架的修饰符Modifier
topBar@Composable () -> Unit顶部栏,通常是 TopAppBar{}
bottomBar@Composable () -> Unit底部栏,通常是 NavigationBar{}
floatingActionButton@Composable () -> Unit悬浮按钮{}
floatingActionButtonPositionFabPosition显示悬浮按钮的位置FabPosition.End
floatingToolbar@Composable () -> Unit悬浮工具栏{}
floatingToolbarPositionToolbarPosition显示悬浮工具栏的位置ToolbarPosition.BottomCenter
snackbarHost@Composable () -> Unit用于显示 Snackbar 的容器,Miuix 不提供此组件{}
popupHost@Composable () -> Unit用于显示弹出窗口的容器{ MiuixPopupHost() }
containerColorColor脚手架的背景颜色MiuixTheme.colorScheme.background
contentWindowInsetsWindowInsets传递给内容的窗口插入边距WindowInsets.statusBars
content@Composable (PaddingValues) -> Unit脚手架的主要内容区域-

FabPosition 选项

选项名说明
Start将悬浮按钮放置在屏幕底部左侧,在底部栏上方
Center将悬浮按钮放置在屏幕底部中央,在底部栏上方
End将悬浮按钮放置在屏幕底部右侧,在底部栏上方
EndOverlay将悬浮按钮放置在屏幕底部右侧,覆盖在底部栏上

ToolbarPosition 选项

选项名说明
TopStart将悬浮工具栏放置在屏幕顶部左侧
CenterStart将悬浮工具栏放置在屏幕左侧垂直居中
BottomStart将悬浮工具栏放置在屏幕底部左侧
TopEnd将悬浮工具栏放置在屏幕顶部右侧
CenterEnd将悬浮工具栏放置在屏幕右侧垂直居中
BottomEnd将悬浮工具栏放置在屏幕底部右侧
TopCenter将悬浮工具栏放置在屏幕顶部水平居中
BottomCenter将悬浮工具栏放置在屏幕底部水平居中

进阶用法

带有顶部栏和底部栏的页面布局

kotlin
val topAppBarScrollBehavior = MiuixScrollBehavior(rememberTopAppBarState())

Scaffold(
    topBar = {
        TopAppBar(
            title = "标题",
            navigationIcon = {
                IconButton(onClick = { /* 处理导航点击 */ }) {
                    Icon(MiuixIcons.Useful.Back, contentDescription = "返回")
                }
            },
            scrollBehavior = topAppBarScrollBehavior
        )
    },
    bottomBar = {
        val items = listOf(
            NavigationItem("首页", MiuixIcons.Useful.NavigatorSwitch),
            NavigationItem("设置", MiuixIcons.Useful.Settings)
        )
        var selectedItem by remember { mutableStateOf(0) }
        NavigationBar(
            items = items,
            selected = selectedItem,
            onClick = { index ->
                selectedItem = index
            },
        )
    },
    content = { paddingValues ->
        // 内容区域需要考虑 padding
        LazyColumn(
            contentPadding = paddingValues,
            modifier = Modifier
                .fillMaxSize()
                // 绑定顶部栏的滚动行为
                .nestedScroll(topAppBarScrollBehavior.nestedScrollConnection)
        ) {
            items(20) { index ->
                SuperArrow(
                    title = "Item $index",
                    onClick = { /* 处理点击 */ }
                )
                if (index < 19) HorizontalDivider()
            }
        }
    }
)

带有悬浮按钮的页面布局

kotlin
Scaffold(
    topBar = {
        SmallTopAppBar(title = "标题")
    },
    floatingActionButton = {
        FloatingActionButton(
            onClick = { /* 处理点击事件 */ }
        ) {
            Icon(MiuixIcons.Useful.New, contentDescription = "添加")
        }
    },
    floatingActionButtonPosition = FabPosition.End,
    content = { paddingValues ->
        // 内容区域需要考虑 padding
        Box(
            modifier = Modifier
                .padding(top = paddingValues.calculateTopPadding(), start = 26.dp)
                .fillMaxSize()
        ) {
               Text("点击右下角按钮添加内容")
        }
    }
)

带有 Snackbar 的页面布局(需要使用 Material 组件)

kotlin
val snackbarHostState = remember { SnackbarHostState() }
val scope = rememberCoroutineScope()

Scaffold(
    snackbarHost = { SnackbarHost(hostState = snackbarHostState) },
    topBar = {
        SmallTopAppBar(title = "标题")
    },
    floatingActionButton = {
        FloatingActionButton(
            onClick = {
                scope.launch {
                    snackbarHostState.showSnackbar("这是一条消息!")
                }
            }
        ) {
            Icon(MiuixIcons.Useful.Info, contentDescription = "显示消息")
        }
    },
    content = { paddingValues ->
        // 内容区域需要考虑 padding
        Box(
            modifier = Modifier
                .padding(top = paddingValues.calculateTopPadding(), start = 26.dp)
                .fillMaxSize()
        ) {
            Text("点击按钮显示 Snackbar")
        }
    }
)

自定义窗口插入边距

kotlin
Scaffold(
    contentWindowInsets = WindowInsets.systemBars,
    topBar = {
        SmallTopAppBar(title = "标题")
    },
    content = { paddingValues ->
        // 内容区域需要考虑 padding
        Box(
            modifier = Modifier
                .padding(top = paddingValues.calculateTopPadding(), start = 26.dp)
                .fillMaxSize()
        ) {
            Text("考虑系统栏的内容区域")
        }
    }
)

基于 Apache-2.0 许可发布