https://kotlinlang.org logo
#compose
Title
# compose
g

Guy Bieber

08/25/2020, 8:12 PM
I have a Text function and want the value to change when I change the state. There is no onChange for Text. Is there another composable I should use.
Changing the mutable state does not change the value. This is a pretty basic use case that used to work with Model. Any help would be appreciated.
r

romainguy

08/25/2020, 9:06 PM
Just do
Text("my state is ${myValue}"
Unless I misunderstand what you're trying to achieve
g

Guy Bieber

08/25/2020, 9:32 PM
I am changing myValue and the Text is not recomposing.
I get a value change over bluetooth and want the new value displayed in a Text element.
m

Mark Murphy

08/25/2020, 10:01 PM
How are you declaring
myValue
?
g

Guy Bieber

08/25/2020, 10:06 PM
Copy code
class BasicStatusDataModel<T> (
    ...
    value : T, // wrapped mutable
    ...
) {

    var value by mutableStateOf(value)
This is ugly but works:
Copy code
package com.nikolamotor.test

import android.os.Bundle
import android.os.Handler
import androidx.appcompat.app.AppCompatActivity
import androidx.compose.foundation.Text
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Surface
import androidx.compose.runtime.Composable
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.platform.setContent

import com.nikolamotor.test.ui.TestTheme

class MainActivity : AppCompatActivity() {

    class Data (
        count : Int = 0
    ) {
        var count = mutableStateOf(count)
    }

    var data = Data()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            TestTheme {
                Surface(color = MaterialTheme.colors.background) {
                    Greeting()
                }
            }
        }
        increment()
    }

    fun increment () {
        Handler(this.getMainLooper()).postDelayed({
            data.count.value++
            increment()
        }, 1000)
    }

    @Composable
    fun Greeting() {
        var data = remember { data }
        Text(text = "Hello ${data.count.value}!")
    }
    
}
Cleaner and also works:
Copy code
package com.nikolamotor.test

import android.os.Bundle
import android.os.Handler
import androidx.appcompat.app.AppCompatActivity
import androidx.compose.foundation.Text
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Surface
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.ui.platform.setContent

import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue

import com.nikolamotor.test.ui.TestTheme

class MainActivity : AppCompatActivity() {

    class Data <T> (
        count : T
    ) {
        var count by mutableStateOf(count)
    }

    var data = Data<Int>(0)

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            TestTheme {
                Surface(color = MaterialTheme.colors.background) {
                    Greeting()
                }
            }
        }
        increment()
    }

    fun increment () {
        Handler(this.getMainLooper()).postDelayed({
            data.count++
            increment()
        }, 1000)
    }

    @Composable
    fun Greeting() {
        var data = remember { data }
        Text(text = "Hello ${data.count}!")
    }

}
r

romainguy

08/25/2020, 10:55 PM
In your original code where is the
var
stored? You may need to
remember{}
it it’s just declared in a composable function
g

Guy Bieber

08/25/2020, 11:27 PM
The problem I believe is I have compose function that uses remember and then calls another compose function that also does a remember. This seems to not make the child function recompose.
It would be nice if there was a compiler check for remember such that it wraps something that is mutableStateOf. This definitely makes things trickier.
Here is what I am doing which doesn’t work:
@Composable
override fun view () { //var mDataModel = remember {dataModel} val drawerState = rememberBottomDrawerState(dataModel.drawerState) BottomDrawerLayout( drawerState = drawerState, gesturesEnabled = true, drawerContent = { drawerView() }, bodyContent = { baseView() } ) } Changing dataModel.drawerState to BottomDrawerValue.Open has no effect.