Colton Idle

    Colton Idle

    1 year ago
    New to compose, but I expected something like this to work but it does not. My activity has a field myTodoList mutableListOf<String> and it has items added to it by another source (right now I have a post delayed handler that waits for 5 seconds, and then adds ten items) and I expect the items to update this Screen composable, but nothing shows. I'm assuming it's because the state can't live in the activity? That actually doesn't really make sense I guess. Just want someone to look this over. Thank you!
    @Composable
    private fun MyActivityScreen(items: List<String>) {
        val myThings = remember { mutableStateOf(items) }
        Column() {
            myThings.value.forEach {
                Text(text = it)
            }
        }
    }
    a

    allan.conda

    1 year ago
    myThings
    is not necessary I think. Use
    items
    directly.
    k

    Kane Shih

    1 year ago
    LiveData.observeAsState() ?
    Colton Idle

    Colton Idle

    1 year ago
    @allan.conda using items directly didn't work.
    @Kane Shih Do I have to use LiveData? What if that's a dependency that I don't want to pull in and I just want to do this with pure compose?
    k

    Kane Shih

    1 year ago
    1 find a way to call
    myThings.setValue
    2 Kotlin Flow or RxJava -> to State
    Colton Idle

    Colton Idle

    1 year ago
    Hm. So I need to use Flow or Rx to use compose?
    k

    Kane Shih

    1 year ago
    or find a way to trigger recomposition
    but I think LiveData is still the best choice in your use case
    Colton Idle

    Colton Idle

    1 year ago
    That's what I thought
    val myThings = remember { mutableStateOf(items) }
    is used for? @Leland Richardson [G] am I doing something wrong here?
    flosch

    flosch

    1 year ago
    Your problem lies not in compose but with your list in your activity. The list needs to be observable if you want your composables to recompose on a change of the items in the list. Either use a Flow<List>, LiveData<List> or mutableStateOf(List), hand that over to your MyActivityScreen and observe it in there.
    Colton Idle

    Colton Idle

    1 year ago
    @flosch so in my activitiy the field is defined as
    val listOfItems = mutableListOf<String>()
    so if I just change that to mutableStateOf I should be good? I will try that now and let you know what happens. Thank you! I was not aware that I couldn't just use a regular list and pass it into a composable and then that composable converts it to an observable (aka. thats what I thought I was doing with my
    val myThings = remember { mutableStateOf(items) }
    statement
    flosch

    flosch

    1 year ago
    Yes that is what it does but only in your composable scope. If you change the value of
    myThings
    then it will be recomposed, but you said you changed
    items
    outside of your composable; that will not work
    Colton Idle

    Colton Idle

    1 year ago
    Oooh. Okay yeah that makes sense. Let me give it a shot. Appreciate your time and explanation @flosch
    @flosch still does not trigger a recomposition it seems. Here is the composable
    @Composable
    private fun MyActivityScreen(items: MutableState<MutableList<String>>) {
        Column() {
            items.value.forEach {
                Text(text = it)
            }
        }
    }
    And my activity defines a field
    val listOfItems = mutableStateOf(mutableListOf<String>())
    and I add to the listOfItems via
    listOfItems.value.add("adsf")
    flosch

    flosch

    1 year ago
    Yea you will probably have to change the value of
    MutableState
    and not of the
    MutableList
    val listOfItems = mutableStateOf(listOf<String>())
    
    @Composable
    private fun MyActivityScreen(items: State<List<String>>) {
        Column() {
            items.value.forEach {
                Text(text = it)
            }
        }
    }
    
    listOfItems.value = listOf("a")
    listOfItems.value = listOf("a", "b" )
    You could also use
    mutableStateListOf
    (LINK)
    Colton Idle

    Colton Idle

    1 year ago
    @flosch That worked! So basically mutable state can't use a mutable class/obj/reference Wish there was a lint check for that maybe? Also wish there was an easy way to take a list and copy or duplicate it. To get around it for now I started doing list.toMutableList() then call add(new value), then .toList(). Seems inefficient?
    flosch

    flosch

    1 year ago
    data class State(val items: List<String>, ...)
    val state = ...
    state.copy(items = ...)
    Immutable objects are the way to go with data driven architectures
    Colton Idle

    Colton Idle

    1 year ago
    Oooh. So just wrap it in a data class. Okay. I just thought it was interesting there was no .copy on a List. 👍 Thank you @flosch!