我正在尝试使我使用 jetpack compose 构建的应用程序的导航窗格正常工作,但我使用版本material3作为脚手架,而我正在学习的视频使用版本1。所以,我不知道如何在 version3 中编写相同的代码。
这是我的 MainActivity.kt 文件
@file:OptIn(ExperimentalMaterial3Api::class, ExperimentalMaterial3Api::class)
package com.example.littlelemonmainscreen
import android.annotation.SuppressLint
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.Column
import androidx.compose.material3.*
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
HomeScreen()
}
}
}
@SuppressLint("UnusedMaterial3ScaffoldPaddingParameter", "SuspiciousIndentation")
@Composable
fun HomeScreen() {
val scaffoldState = rememberScaffoldState() //First Error. Not able to use
val scope = rememberCoroutineScope()
Scaffold(
scaffoldState = scaffoldState, //Second Error. On LHS side, scaffoldState is turning red and showing error cannot find parameter scaffoldState
topBar = {
TopAppBar(scaffoldState = scaffoldState, scope = scope) // Fourth Error. Cannot find parameter scaffoldState, scope error
}
) {
Column {
UpperPanel()
LowerPanel()
}
}
}
//Here is my DrawerPanel function
@Composable
fun DrawerPanel(scaffoldState: BottomSheetScaffoldState? = null, scope: CoroutineScope? = null) {
List(10) { Text(text = "item $it", modifier = Modifier.padding(horizontal = 20.dp, vertical = 10.dp)) }
IconButton(onClick = {
scope?.launch { scaffoldState?.drawerState?.open() } //Fifth Error. Not able to use drawerState.open()
}) {
Icon(imageVector = Icons.Default.ExitToApp, contentDescription = "Icon Close")
}
}
Scaffold
文档。在那里你可以看到,实际上,不再支持 scaffoldState
参数了:
@Composable
fun Scaffold(
modifier: Modifier = Modifier,
topBar: @Composable () -> Unit = {},
bottomBar: @Composable () -> Unit = {},
snackbarHost: @Composable () -> Unit = {},
floatingActionButton: @Composable () -> Unit = {},
floatingActionButtonPosition: FabPosition = FabPosition.End,
containerColor: Color = MaterialTheme.colorScheme.background,
contentColor: Color = contentColorFor(containerColor),
contentWindowInsets: WindowInsets = ScaffoldDefaults.contentWindowInsets,
content: @Composable (PaddingValues) -> Unit
): Unit
其原因是,之前包含在
scaffoldState
中的抽屉状态管理和小吃栏状态管理现在由 Drawer
和 Snackbar
可组合项 本身处理。
看看 可组合:
@Composable
fun ModalNavigationDrawer(
drawerContent: @Composable () -> Unit,
modifier: Modifier = Modifier,
drawerState: DrawerState = rememberDrawerState(DrawerValue.Closed),
gesturesEnabled: Boolean = true,
scrimColor: Color = DrawerDefaults.scrimColor,
content: @Composable () -> Unit
): Unit
看看 可组合:
@Composable
fun SnackbarHost(
hostState: SnackbarHostState,
modifier: Modifier = Modifier,
snackbar: @Composable (SnackbarData) -> Unit = { Snackbar(it) }
): Unit
因此,带有 Scaffold
和
ModalNavigationDrawer
的
SnackbarHost
看起来像这样:
val drawerState = rememberDrawerState(DrawerValue.Closed)
val scope = rememberCoroutineScope()
// icons to mimic drawer destinations
val items = listOf(
Icons.Default.AccountCircle,
Icons.Default.Bookmarks,
Icons.Default.Dashboard
)
val selectedItem = remember { mutableStateOf(items[0]) }
ModalNavigationDrawer(
drawerState = drawerState,
drawerContent = {
ModalDrawerSheet(drawerState) {
Column(Modifier.verticalScroll(rememberScrollState())) {
Spacer(Modifier.height(12.dp))
items.forEach { item ->
NavigationDrawerItem(
icon = { Icon(item, contentDescription = null) },
label = { Text(item.name) },
selected = item == selectedItem.value,
onClick = {
scope.launch { drawerState.close() }
selectedItem.value = item
},
modifier = Modifier.padding(NavigationDrawerItemDefaults.ItemPadding)
)
}
}
}
},
snackbarHost = { SnackbarHost(snackbarHostState) },
floatingActionButton = {
var clickCount by remember { mutableStateOf(0) }
ExtendedFloatingActionButton(
onClick = {
scope.launch {
snackbarHostState.showSnackbar(
"Snackbar # ${++clickCount}"
)
}
}
) { Text("Show snackbar") }
},
content = {
Column(
modifier = Modifier
.fillMaxSize()
.padding(16.dp),
horizontalAlignment = Alignment.CenterHorizontally
) {
Text(text = if (drawerState.isClosed) ">>> Swipe >>>" else "<<< Swipe <<<")
Spacer(Modifier.height(20.dp))
Button(onClick = { scope.launch { drawerState.open() } }) {
Text("Click to open")
}
}
}
)
我希望这足以帮助您将现有代码迁移到material3
。