Home > front end >  Updating a Composable Function with a Lambda
Updating a Composable Function with a Lambda

Time:09-16

In the Android developer docs at the following web address: https://developer.android.com/jetpack/compose/mental-model#recomposition

There is a composable function which is given as the following:

@Composable
fun ClickCounter(clicks: Int, onClick: () -> Unit) {
    Button(onClick = onClick) {
        Text("I've been clicked $clicks times")
    }
}

It's said in the text that this produces an element which updates the number of times its been clicked every time it is clicked. However, looking at it, it seems to need a lambda function to do that.

When I try and put it into the SetContent function I get the following:

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            WorkTimerTheme {
                Conversation(SampleData.conversationSample)
                ClickCounter(clicks = 0) {
                    //Insert My Function Here
                }
            }
        }
    }
}

The comment //Insert My Function Here has been added by me. I presume that within this I have to put a Lambda which updates the clicks value of the composable, but I have no idea what to put. Does anyone know an acceptable way of writing this?

CodePudding user response:

You need a MutableState to trigger recomposition and remember{} to keep previous value when recomposition occurred.

I asked a question about it and my question contains answer to your question.

@Composable
fun MyScreenContent(names: List<String> = listOf("Android", "there")) {
    val counterState = remember { mutableStateOf(0) }

    Column(modifier = Modifier.fillMaxHeight()) {

        Counter(
            count = counterState.value,
            updateCount = { newCount ->
                counterState.value = newCount
            }
        )
    }
}


@Composable
fun Counter(count: Int, updateCount: (Int) -> Unit) {
    Button(
        onClick = { updateCount(count   1) },

    ) {
        Text("I've been clicked $count times")
    }
}

CodePudding user response:

Thanks very much to @Thracian for linking a similar question. As the answer to mine is related yet slightly different I thought I would post my own.

The correct code is as follows:

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {

            val counterState = remember { mutableStateOf(0) }

            WorkTimerTheme {
                Conversation(SampleData.conversationSample)
                ClickCounter(clicks = counterState.value) {
                        counterState.value  
                }
            }
        }
    }
}

As suggested I added a mutableState value which appears to remember the value of something at the last "recomposition", unless it is explicitly updated. If a mutablestate is explicitly updated that will trigger a recomposition (as noted in the answer to @Thracian's question).

A recomposition will redraw the Element.

In order to update the value at recomposition the number of times the button has been clicked must be stored in the mutablestate and passed to the Composable Function at each recomposition.

Using the Composable functions Lambda argument to affect the mutable state completes the loop, updating the mutablestate which then recomposes the button with the updated value.

That is the purpose of counterState.value .

As suggested above for more information on this, try reading this documentation: https://developer.android.com/jetpack/compose/state#viewmodel-state

The video is related to what we're discussing here.

  • Related