https://kotlinlang.org logo
z

zoha131

12/22/2020, 3:46 AM
is there any way to change two different state at the same time without recomposing?
a

Adam Powell

12/22/2020, 3:55 AM
withMutableSnapshot
will let you commit several snapshot state changes atomically and compose will see it as a single change. In some cases it's redundant or overkill though, what's your use case?
👍 2
z

zoha131

12/22/2020, 4:24 AM
I am using
ModalBottomSheetLayout
and I have to show different
BottomSheet
based on user action. Now if i change the
bottomSheetState
first then I can’t get the updated other state inside the
sheetBlock
Copy code
sealed class StudentEditSheet{
    object Email: StudentEditSheet()
    object Gender: StudentEditSheet()
    object Department: StudentEditSheet()
    object Level: StudentEditSheet()
    object Term: StudentEditSheet()
    object None: StudentEditSheet()
}

@ExperimentalComposeApi
@OptIn(ExperimentalMaterialApi::class)
@Composable
fun StudentEditScreen(
    viewModel: StudentEditViewModel,
    onBackPress: (() -> Unit)?,
    onNavigateToHome: () -> Unit
) {
    val sheetState = rememberModalBottomSheetState(ModalBottomSheetValue.Hidden)
    var studentEditSheet by remember { mutableStateOf<StudentEditSheet>(StudentEditSheet.None) }

    ModalBottomSheetLayout(
        sheetState = sheetState,
        sheetContent = {
            when (studentEditSheet) {
                StudentEditSheet.Gender -> {
                    ListBottomSheet(
                        title = stringResource(id = R.string.select_your_department),
                        icon = Icons.Outlined.DepartureBoard,
                        onClose = { studentEditSheet = StudentEditSheet.None },
                        list = (0..9).toList(),
                        onItemClick = { }
                    )
                }

                else -> {
                    Box(modifier = Modifier.size(100.dp))
                }
            }
        }
    ) {
        StudentEditScreenContent(
            stateFlow = viewModel.state,
            onFullNameChange = viewModel::changeFullName,
            onDiuIdChange = viewModel::changeDiuId,
            selectGender = {
                withMutableSnapshot {
                    sheetState.show()
                    studentEditSheet = StudentEditSheet.Gender
                }
            },
            onEmailClick = { studentEditSheet = StudentEditSheet.Email },
            onPhoneChange = viewModel::changePhoneNumber,
            selectDepartment = { studentEditSheet = StudentEditSheet.Department },
            selectLevel = { studentEditSheet = StudentEditSheet.Level },
            selectTerm = { studentEditSheet = StudentEditSheet.Term },
            changeImage = {},
            saveStudentProfile = viewModel::saveProfile,
            onBackPress = onBackPress
        )
    }
}
I think I am doing it wrong….
a

Adam Powell

12/22/2020, 4:56 AM
I'd have to give it a closer look than I can spare tonight to see what exactly is amiss, but I doubt it has to do with snapshot atomicity. Compose user input events all dispatch on the android main thread and compose will coalesce updates no more often than every
Choreographer
frame synced to the device's vsync interval; if you make two changes in the same event handler it's basically as good as putting it inside a
withMutableSnapshot
block anyway
(since
Choreographer
work also happens on the same thread as the event callbacks; they cannot run concurrently)
z

zoha131

12/22/2020, 5:16 AM
i have also tried reorganizing the state changes.
Copy code
studentEditSheet = StudentEditSheet.Gender
sheetState.show()
but I have the same effect. It ignores the first tap.
a

Adam Powell

12/22/2020, 5:19 AM
hmm, can you file an issue on the bug tracker and we'll take a look after the holidays? If you have an isolated repro it seems worth looking into
z

zoha131

12/22/2020, 5:20 AM
ok. I will file a but with an isolated repro.
👍 2
j

József Szilvási

01/15/2021, 7:18 AM
@zoha131 can you please link the issue you filed? thanks
z

zoha131

01/15/2021, 4:36 PM
i didn’t file any issue. I was unable to reproduce this in a fresh project. But somehow it is not working in my project.