Как изменить содержимое внутри Scaffold, которое существует внутри ящика в Jetpack Compose?
У меня есть этот ящик:
val drawerState = rememberDrawerState(DrawerValue.Closed)
val scope = rememberCoroutineScope()
val items = listOf(Icons.Default.Favorite, Icons.Default.Face, Icons.Default.Email)
val selectedItem = remember { mutableStateOf(items[0]) }
ModalNavigationDrawer(
drawerState = drawerState,
drawerContent = {
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
//How to change the content of Scaffold's content section?
},
modifier = Modifier.padding(NavigationDrawerItemDefaults.ItemPadding)
)
}
},
content = {
Scaffold(
topBar = {
//
},
content = { padding ->
Text(
modifier = Modifier.padding(padding),
text = "Favorites"
)
}
)
}
)
Теперь, когда я запускаю приложение, я получаю правильный TopBar и прямо под ним текст, который содержит значение «Избранное». Проблема в том, что я всегда хочу иметь один и тот же TopBar и менять только содержимое Scaffold. Поэтому вместо «Избранное» я хочу отображать «Лицо» при нажатии второго элемента.
Я хотел создать некоторые составные функции для отображения данных, но я не могу вызывать их изнутри onClick. Android Studio жалуется на:
Вызовы @Composable могут происходить только из контекста функции @Composable.
Я также думал о создании состояний и загрузке этих данных в соответствии с этим состоянием. Но не так ли сложно отображать только один текст?
Мы также думали о переходе на другие экраны, но это означает, что каждый экран должен иметь свой собственный TopBar, что, на мой взгляд, требует усложнения приложения без всякой причины. Я полностью потерян. Как решить эту проблему?
2 ответа
Вы должны просто обновить значение состояния модели представления в onclick и прослушать это значение внутри вашего компонуемого. Когда значение изменяется, вы можете просто вызвать другой компонуемый. Это не так сложно.
Создание состояния для изменения контента не так сложно, как и размещение компонуемого NavHost внутри вашего блока контента.
object Routes {
const val Favorites = "Favorites"
const val Faces = "Faces"
}
var route by remember {mutableStateOf(Routes.Favorites)}
ModalNavigationDrawer(
drawerState = drawerState,
drawerContent = {
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
// Change route
route = some new route...
},
modifier = Modifier.padding(NavigationDrawerItemDefaults.ItemPadding)
)
}
},
content = {
Scaffold(
topBar = {
//
},
content = { padding ->
if(route == Routes.Favorites) {
Text(
modifier = Modifier.padding(padding),
text = "Favorites"
)
}else {
// other routes
}
}
)
}
)
С NavHost
NavHost(
navController = navController,
startDestination = Routes.Favorites
) {
composable(Routes.Favorites) {
Favorites()
}
composable(Routes. Face) {
Faces()
}
}