Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Jetpack Compose saving state on orientation change

I am using Android Jetpack's Compose and have been trying to figure out how to save state for orientation changes.

My train of thought was making a class a ViewModel. As that generally worked when I would work with Android's traditional API.

I have used remember {} and mutableState {} to update the UI when information has been changed. Please validate if my understanding is correct...

remember = Saves the variable and allows access via .value, this allows values to be cache. But its main use is to not reassign the variable on changes.

mutableState = Updates the variable when something is changed.

Many blog posts say to use @Model, however, the import gives errors when trying that method. So, I added a : ViewModel()

However, I believe my remember {} is preventing this from working as intended?

Can I get a point in the right direction?

@Composable
fun DefaultFlashCard() {

    val flashCards = remember { mutableStateOf(FlashCards())}
    

    Spacer(modifier = Modifier.height(30.dp))

    MaterialTheme {


        val typography = MaterialTheme.typography
        var question = remember { mutableStateOf(flashCards.value.currentFlashCards.question) }



        Column(modifier = Modifier.padding(30.dp).then(Modifier.fillMaxWidth())
                .then(Modifier.wrapContentSize(Alignment.Center))
                .clip(shape = RoundedCornerShape(16.dp))) {
            Box(modifier = Modifier.preferredSize(350.dp)
                    .border(width = 4.dp,
                            color = Gray,
                            shape = RoundedCornerShape(16.dp))
                    .clickable(
                            onClick = {
                                question.value = flashCards.value.currentFlashCards.answer })
                    .gravity(align = Alignment.CenterHorizontally),
                    shape = RoundedCornerShape(2.dp),
                    backgroundColor = DarkGray,
                    gravity = Alignment.Center) {
                Text("${question.value}",
                        style = typography.h4, textAlign = TextAlign.Center, color = White
                )
            }
        }

        Column(modifier = Modifier.padding(16.dp),
                horizontalGravity = Alignment.CenterHorizontally) {

            Text("Flash Card application",
                    style = typography.h6,
                    color = Black)

            Text("The following is a demonstration of using " +
                    "Android Compose to create a Flash Card",
                    style = typography.body2,
                    color = Black,
                    textAlign = TextAlign.Center)

            Spacer(modifier = Modifier.height(30.dp))
            Button(onClick = {
                flashCards.value.incrementQuestion();
                question.value = flashCards.value.currentFlashCards.question },
                    shape = RoundedCornerShape(10.dp),
                    content = { Text("Next Card") },
                    backgroundColor = Cyan)
        }
    }
}


data class Question(val question: String, val answer: String) {
}


class FlashCards: ViewModel() {

    var flashCards = mutableStateOf( listOf(
            Question("How many Bananas should go in a Smoothie?", "3 Bananas"),
            Question("How many Eggs does it take to make an Omellete?", "8 Eggs"),
            Question("How do you say Hello in Japenese?", "Konichiwa"),
            Question("What is Korea's currency?", "Won")
    ))

    var currentQuestion = 0

    val currentFlashCards
        get() = flashCards.value[currentQuestion]

    fun incrementQuestion() {
        if (currentQuestion + 1 >= flashCards.value.size) currentQuestion = 0 else currentQuestion++
    }
}

like image 858
PandaPlaysAll Avatar asked Dec 06 '25 14:12

PandaPlaysAll


1 Answers

There is another approach to handle config changes in Compose, it is rememberSaveable. As docs says:

While remember helps you retain state across recompositions, the state is not retained across configuration changes. For this, you must use rememberSaveable. rememberSaveable automatically saves any value that can be saved in a Bundle. For other values, you can pass in a custom saver object.

It seems that Mohammad's solution is more robust, but this one seems simpler.

like image 99
Matheus Ribeiro Lima Avatar answered Dec 08 '25 03:12

Matheus Ribeiro Lima



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!