escodro
03/26/2021, 10:52 AMSaver
to be used with rememberSaveable
. Could you please help me?
I have a list of items that, when clicked, shows a BottomSheet
with the item data. Implementing my custom Saver
works only or the first time and the first item saved will show every time the screen is rotate.
When in portrait or landscape, if I click in any item, it shows the item correctly. But when rotate, the first one saved is shown again.
Code is in the comments.
Thanks a lot in advance! ❤️escodro
03/26/2021, 10:52 AM@Stable
internal class CategoryBottomSheetState(val category: Category) {
private val id by mutableStateOf(category.id)
var name by mutableStateOf(category.name)
var color by mutableStateOf(category.color)
fun isEditing(): Boolean =
id > 0L
fun toCategory(): Category =
Category(
id = id,
name = name,
color = color
)
companion object {
fun Saver(): Saver<CategoryBottomSheetState, *> = Saver(
save = { state -> state.toCategory() },
restore = { category -> CategoryBottomSheetState(category) }
)
}
}
@Composable
internal fun rememberCategoryBottomSheetState(vararg key: Any?, category: Category) =
rememberSaveable(key, stateSaver = CategoryBottomSheetState.Saver()) {
mutableStateOf(CategoryBottomSheetState(category))
}
escodro
03/26/2021, 10:53 AMval state by rememberCategoryBottomSheetState(category, category = category)
Changing the state:
CategoryNameField(
name = state.name,
onNameChange = { state.name = it },
modifier = Modifier.weight(5F)
)
escodro
03/26/2021, 11:12 AMinputs
and key
for the remember did work. However, if I updated some value before rotating, it does not show the updated value.🤔
Is it expected? I have to provide different keys for both the remember
and the bundle
?escodro
03/26/2021, 11:13 AM@Composable
internal fun rememberCategoryBottomSheetState(vararg key: Any?, category: Category) =
rememberSaveable(key, key = category.toString(), stateSaver = CategoryBottomSheetState.Saver()) {
mutableStateOf(CategoryBottomSheetState(category))
}
escodro
03/26/2021, 11:44 AMAndrey Kulikov
03/26/2021, 12:20 PM*key
instead of key
to rememberSaveable. similarly how it is done here: https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:compose/[…]aveable.kt;l=140;drc=dd000ea5e6eb3a8f07b869595ca62aa2fb781d12Andrey Kulikov
03/26/2021, 12:21 PMescodro
03/26/2021, 12:27 PM@Composable
internal fun rememberCategoryBottomSheetState(vararg key: Any?, category: Category) =
rememberSaveable(*key, key = category.toString(), stateSaver = CategoryBottomSheetState.Saver()) {
mutableStateOf(CategoryBottomSheetState(category))
}
But I had to keep the “bundle key” as well, otherwise the issue happens again.
Is it okay?Andrey Kulikov
03/26/2021, 12:40 PMval bottomContent by
which means you never update the state. can you show more code?escodro
03/26/2021, 12:42 PMescodro
03/26/2021, 12:45 PM@Composable
fun CategoryBottomSheet(category: Category?, onHideBottomSheet: () -> Unit) {
val bottomSheetState by rememberCategoryBottomSheetState(category, category = category)
CategorySheetLoader(
colorList = CategoryColors.values().toList(),
bottomSheetState = bottomSheetState,
onHideBottomSheet = onHideBottomSheet
)
}
@Composable
private fun CategorySheetLoader(
editViewModel: CategoryEditViewModel = getViewModel(),
bottomSheetState: CategoryBottomSheetState,
colorList: List<Color>,
onHideBottomSheet: () -> Unit,
) {
CategorySheetContent(
colorList = colorList,
state = bottomSheetState,
onCategoryChange = { updatedState ->
editViewModel.updateCategory(updatedState.toCategory())
onHideBottomSheet()
},
)
}
@Composable
private fun CategorySheetContent(
state: CategoryBottomSheetState,
colorList: List<Color>,
onCategoryChange: (CategoryBottomSheetState) -> Unit,
) {
Column(modifier = Modifier.padding(16.dp), verticalArrangement = Arrangement.SpaceAround) {
Row(verticalAlignment = Alignment.CenterVertically) {
CategoryNameField(
name = state.name,
onNameChange = { state.name = it },
modifier = Modifier.weight(5F)
)
CategoryColorSelector(
colorList = colorList,
value = Color(state.color),
onColorChange = { state.color = it.toArgb() }
)
CategorySaveButton(
currentColor = Color(state.color),
onClick = { onCategoryChange(state) }
)
}
}
}
Andrey Kulikov
03/26/2021, 12:53 PMescodro
03/26/2021, 1:03 PMAndrey Kulikov
03/26/2021, 1:33 PMcategory.id
as a vararg param and remove your own bundle key.escodro
03/26/2021, 1:42 PM@Composable
internal fun rememberCategoryBottomSheetState(category: Category) =
rememberSaveable(category.id, stateSaver = CategoryBottomSheetState.Saver) {
mutableStateOf(CategoryBottomSheetState(category))
}
If so, it seems very similar to the my first attempt.Andrey Kulikov
03/27/2021, 11:44 PMescodro
03/29/2021, 11:13 AMcategory.id
, it would “refresh” the stored value.Andrey Kulikov
03/29/2021, 11:21 AMescodro
03/29/2021, 11:23 AMAndrey Kulikov
03/29/2021, 11:24 AM@Composable
internal fun rememberCategoryBottomSheetState(category: Category) =
key(category.id) {
rememberSaveable(stateSaver = CategoryBottomSheetState.Saver) {
mutableStateOf(CategoryBottomSheetState(category))
}
}
please try this variant for nowescodro
03/29/2021, 11:27 AMAndrey Kulikov
03/29/2021, 11:38 AMescodro
03/29/2021, 11:45 AM