Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

311
Visualizações
Jetpack Compose: MutableState<Boolean> not working as intended

In our Android app we want to introduce Compose to a simple debug screen, where we can enable/disable SharedPreferences. I'm trying to get that running using Compose' interface MutableState - but it does not work how I think it does. My plan is to temporarily use MutableState to set a boolean in SharedPreferences (before migrating to DataStore later).

Here is what I had in mind:

private class MyOwnState(startWith: Boolean) : MutableState<Boolean> {
    override var value: Boolean = startWith
    override fun component1(): Boolean = value
    override fun component2(): (Boolean) -> Unit = { value = it }
}

// then, in composable:
var value by remember { MyOwnState(false) }

Of course in real life I would overwrite the getter+setter of the value - but this example is enough, because it does not work. The state change is not propagated and the UI is not updated.

To illustrate this, I but together the code snippets by remember { mutableStateOf(false) } and by remember { MyOwnState(false) }. The first one works (switch is updated), the second one does not.

Full code:

@Composable
fun SomeStateExamples() {
    Column {
        SwitchWorks()
        SwitchDoesNotWork()
    }
}

@Composable
fun SwitchWorks() {
    var value by remember { mutableStateOf(false) }
    Switch(checked = value, onCheckedChange = { value = it })
}

@Composable
fun SwitchDoesNotWork() {
    var value by remember { MyOwnState(false) }
    Switch(checked = value, onCheckedChange = { value = it })
}


private class MyOwnState(startWith: Boolean) : MutableState<Boolean> {
    override var value: Boolean = startWith
    override fun component1(): Boolean = value
    override fun component2(): (Boolean) -> Unit = { value = it }
}

The first switch is togglable, the second one is not:

first switch works, second one does not

What am I missing? The MutableState interface is pretty simple, and stable - and I didn't find any extra methods (aka invalidate, notifyListeners, ...) that I need to call.

Thank you for your help! 🙏

over 4 years ago · Santiago Trujillo
3 Respostas
Responde à pergunta

0

Adding to Johan's answer, it looks like you also need to implement StateObject to fetch the value and update thd snapshot system. By having a look at SnapshotMutableStateImpl

override var value: T
        get() = next.readable(this).value
        set(value) = next.withCurrent {
            if (!policy.equivalent(it.value, value)) {
                next.overwritable(this, it) { this.value = value }
            }
        }

private var next: StateStateRecord<T> = StateStateRecord(value)

override val firstStateRecord: StateRecord
    get() = next

You will see that using StateObject makes you work with StateRecords where you store the updatable value, read it and update it.

over 4 years ago · Santiago Trujillo Relatório

0

Not an answer directly, but looking at how mutableStateOf works, it's also calling createSnapshotMutableState(value, policy) behind the scenes.

So I don't think just inheriting MutableState and changing that will cause Compose to initiate a recomposition and thus updating the UI.

I would probably instead try to pass in the state of the UI from outside as a model with ViewModel or LiveData and mutate that model data.

over 4 years ago · Santiago Trujillo Relatório

0

In your MyOwnState class you have to implement private mutableState value like this:

private class MyOwnState(startWith: Boolean) : MutableState<Boolean> {
    private var _value by mutableStateOf(startWith)
    override var value: Boolean = startWith
        get() = _value
        set(value) {
            _value = value
            field = value
        }
    override fun component1(): Boolean = value
    override fun component2(): (Boolean) -> Unit = { value = it }
}

When you will try to change value inside composable, composition will recompose because you also changed MutableState _value. Read more about how state works in Jetpack Compose here.

over 4 years ago · Santiago Trujillo Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda