|
| 1 | +# Scaffold |
| 2 | + |
| 3 | +`Scaffold` 是 Miuix 中的脚手架组件,用于实现基本的 MIUIX 设计视觉布局结构。它提供了应用程序界面的基本框架,包括顶部栏、底部栏、悬浮按钮等元素的容器。 |
| 4 | + |
| 5 | +## 引入 |
| 6 | + |
| 7 | +```kotlin |
| 8 | +import top.yukonga.miuix.kmp.basic.Scaffold |
| 9 | +``` |
| 10 | + |
| 11 | +## 基本用法 |
| 12 | + |
| 13 | +Scaffold 组件可以构建带有顶栏的页面布局: |
| 14 | + |
| 15 | +```kotlin |
| 16 | +Scaffold( |
| 17 | + topBar = { |
| 18 | + SmallTopAppBar(title = "标题" ) |
| 19 | + }, |
| 20 | + content = { paddingValues -> |
| 21 | + // 内容区域需要考虑 padding |
| 22 | + Box( |
| 23 | + modifier = Modifier |
| 24 | + .padding(top = paddingValues.calculateTopPadding(), start = 26.dp) |
| 25 | + .fillMaxSize() |
| 26 | + ) { |
| 27 | + Text("内容区域") |
| 28 | + } |
| 29 | + } |
| 30 | +) |
| 31 | +``` |
| 32 | + |
| 33 | +## 属性 |
| 34 | + |
| 35 | +### Scaffold 属性 |
| 36 | + |
| 37 | +| 属性名 | 类型 | 默认值 | 说明 | |
| 38 | +| ---------------------------- | ----------------------------------- | --------------------------------- | -------------------------------------------- | |
| 39 | +| modifier | Modifier | Modifier | 应用于脚手架的修饰符 | |
| 40 | +| topBar | @Composable () -> Unit | {} | 顶部栏,通常是 TopAppBar | |
| 41 | +| bottomBar | @Composable () -> Unit | {} | 底部栏,通常是 NavigationBar | |
| 42 | +| floatingActionButton | @Composable () -> Unit | {} | 悬浮按钮 | |
| 43 | +| floatingActionButtonPosition | MiuixFabPosition | MiuixFabPosition.End | 显示悬浮按钮的位置 | |
| 44 | +| snackbarHost | @Composable () -> Unit | {} | 用于显示 Snackbar 的容器,Miuix 不提供此组件 | |
| 45 | +| popupHost | @Composable () -> Unit | \{ MiuixPopupHost() } | 用于显示弹出窗口的容器 | |
| 46 | +| containerColor | Color | MiuixTheme.colorScheme.background | 脚手架的背景颜色 | |
| 47 | +| contentWindowInsets | WindowInsets | WindowInsets.statusBars | 传递给内容的窗口插入边距 | |
| 48 | +| content | @Composable (PaddingValues) -> Unit | - | 脚手架的主要内容区域 | |
| 49 | + |
| 50 | +### MiuixFabPosition 选项 |
| 51 | + |
| 52 | +| 选项名 | 说明 | |
| 53 | +| ---------- | ------------------------------------------ | |
| 54 | +| Start | 将悬浮按钮放置在屏幕底部左侧,在底栏上方 | |
| 55 | +| Center | 将悬浮按钮放置在屏幕底部中央,在底栏上方 | |
| 56 | +| End | 将悬浮按钮放置在屏幕底部右侧,在底栏上方 | |
| 57 | +| EndOverlay | 将悬浮按钮放置在屏幕底部右侧,覆盖在底栏上 | |
| 58 | + |
| 59 | +## 进阶用法 |
| 60 | + |
| 61 | +### 带有顶栏和底栏的页面布局 |
| 62 | + |
| 63 | +```kotlin |
| 64 | +val topAppBarScrollBehavior = MiuixScrollBehavior(rememberTopAppBarState()) |
| 65 | +Scaffold( |
| 66 | + topBar = { |
| 67 | + TopAppBar( |
| 68 | + title = "标题", |
| 69 | + navigationIcon = { |
| 70 | + IconButton(onClick = { /* 处理导航点击 */ }) { |
| 71 | + Icon(MiuixIcons.Useful.Back, contentDescription = "返回") |
| 72 | + } |
| 73 | + }, |
| 74 | + scrollBehavior = topAppBarScrollBehavior |
| 75 | + ) |
| 76 | + }, |
| 77 | + bottomBar = { |
| 78 | + val items = listOf( |
| 79 | + NavigationItem("首页", MiuixIcons.Useful.NavigatorSwitch), |
| 80 | + NavigationItem("设置", MiuixIcons.Useful.Settings) |
| 81 | + ) |
| 82 | + var selectedItem by remember { mutableStateOf(0) } |
| 83 | + NavigationBar( |
| 84 | + items = items, |
| 85 | + selected = selectedItem, |
| 86 | + onClick = { index -> |
| 87 | + selectedItem = index |
| 88 | + }, |
| 89 | + ) |
| 90 | + }, |
| 91 | + content = { paddingValues -> |
| 92 | + // 内容区域需要考虑 padding |
| 93 | + // 绑定顶栏的滚动行为 |
| 94 | + LazyColumn( |
| 95 | + contentPadding = paddingValues, |
| 96 | + topAppBarScrollBehavior = topAppBarScrollBehavior, |
| 97 | + modifier = Modifier.fillMaxSize() |
| 98 | + ) { |
| 99 | + items(20) { index -> |
| 100 | + SuperArrow( |
| 101 | + title = "Item $index", |
| 102 | + onClick = { /* 处理点击 */ } |
| 103 | + ) |
| 104 | + if (index < 19) HorizontalDivider() |
| 105 | + } |
| 106 | + } |
| 107 | + } |
| 108 | +) |
| 109 | +``` |
| 110 | + |
| 111 | +### 带有悬浮按钮的页面布局 |
| 112 | + |
| 113 | +```kotlin |
| 114 | +Scaffold( |
| 115 | + topBar = { |
| 116 | + SmallTopAppBar(title = "标题") |
| 117 | + }, |
| 118 | + floatingActionButton = { |
| 119 | + FloatingActionButton( |
| 120 | + onClick = { /* 处理点击事件 */ } |
| 121 | + ) { |
| 122 | + Icon(MiuixIcons.Useful.New, contentDescription = "添加") |
| 123 | + } |
| 124 | + }, |
| 125 | + floatingActionButtonPosition = MiuixFabPosition.End, |
| 126 | + content = { paddingValues -> |
| 127 | + // 内容区域需要考虑 padding |
| 128 | + Box( |
| 129 | + modifier = Modifier |
| 130 | + .padding(top = paddingValues.calculateTopPadding(), start = 26.dp) |
| 131 | + .fillMaxSize() |
| 132 | + ) { |
| 133 | + Text("点击右下角按钮添加内容") |
| 134 | + } |
| 135 | + } |
| 136 | +) |
| 137 | +``` |
| 138 | + |
| 139 | +### 带有 Snackbar 的页面布局(需要使用 Material 组件) |
| 140 | + |
| 141 | +```kotlin |
| 142 | +val snackbarHostState = remember { SnackbarHostState() } |
| 143 | +val scope = rememberCoroutineScope() |
| 144 | +Scaffold( |
| 145 | + snackbarHost = { SnackbarHost(hostState = snackbarHostState) }, |
| 146 | + topBar = { |
| 147 | + SmallTopAppBar(title = "标题") |
| 148 | + }, |
| 149 | + floatingActionButton = { |
| 150 | + FloatingActionButton( |
| 151 | + onClick = { |
| 152 | + scope.launch { |
| 153 | + snackbarHostState.showSnackbar("这是一条消息!") |
| 154 | + } |
| 155 | + } |
| 156 | + ) { |
| 157 | + Icon(MiuixIcons.Useful.Info, contentDescription = "显示消息") |
| 158 | + } |
| 159 | + }, |
| 160 | + content = { paddingValues -> |
| 161 | + // 内容区域需要考虑 padding |
| 162 | + Box( |
| 163 | + modifier = Modifier |
| 164 | + .padding(top = paddingValues.calculateTopPadding(), start = 26.dp) |
| 165 | + .fillMaxSize() |
| 166 | + ) { |
| 167 | + Text("点击按钮显示 Snackbar") |
| 168 | + } |
| 169 | + } |
| 170 | +) |
| 171 | +``` |
| 172 | + |
| 173 | +### 自定义窗口插入边距 |
| 174 | + |
| 175 | +```kotlin |
| 176 | +Scaffold( |
| 177 | + contentWindowInsets = WindowInsets.systemBars, |
| 178 | + topBar = { |
| 179 | + SmallTopAppBar(title = "标题") |
| 180 | + }, |
| 181 | + content = { paddingValues -> |
| 182 | + // 内容区域需要考虑 padding |
| 183 | + Box( |
| 184 | + modifier = Modifier |
| 185 | + .padding(top = paddingValues.calculateTopPadding(), start = 26.dp) |
| 186 | + .fillMaxSize() |
| 187 | + ) { |
| 188 | + Text("考虑系统栏的内容区域") |
| 189 | + } |
| 190 | + } |
| 191 | +) |
| 192 | +``` |
0 commit comments