-1

I have a dialog with header, message, input string and 2 buttons based on AlertDialog. Full code is here

Before refactoring my buttons recomposed when user enters text, I change it, but did not touch the message. And after that suddenly message starts to recompose when user enters text. The picture is like this now. enter image description here

I did investigate this, but with no luck. If I change the message with simple constant like "message" the recompositing is not happen. If I change the message with constant stringResourse(...) inside dialog (not in screen function) the recompositing is not happen. May be this is a bug in compose?

Nikola Despotoski
  • 49,966
  • 15
  • 119
  • 148
Foenix
  • 376
  • 4
  • 18
  • Jetpack Compose looks for nearest scope for recomposition. A scope is a Composable function that is non-inline returns unit. Wrapping your function with a non-inline function creates this scope. You can refer these answers. https://stackoverflow.com/questions/70257459/jetpack-compose-smart-recomposition https://stackoverflow.com/questions/71045838/why-does-mutablestateof-without-remember-work-sometimes?noredirect=1&lq=1 – Thracian Mar 15 '23 at 18:56
  • how would you explain my last note about changing message to constant or stringResourse? – Foenix Mar 16 '23 at 22:27
  • @Foenix How do you check that it is not recomposed? – Gabriele Mariotti Mar 17 '23 at 08:27
  • @GabrieleMariotti, it is white in Layout Inspector , also it says 0. – Foenix Mar 17 '23 at 13:29
  • @Foenix check with the colors, not with the layout inspector. – Gabriele Mariotti Mar 17 '23 at 13:39

1 Answers1

1

It happens because when the text state is updated all the composables in the nearest scope are recomposed. The same happens also with a static text.

The message and the text are in the same scope (also the text counter)

Text(text = message)
TextField( 
     value = text,
     onValueChange = {
          text = it
     }
)

You can check visually using:

fun getRandomColor() =  Color(
    red = Random.nextInt(256),
    green = Random.nextInt(256),
    blue = Random.nextInt(256),
    alpha = 255
)

and:

Text(text = "message", color = getRandomColor())
TextField(
      value = text,
      onValueChange = {
          text = it
      },
      colors = TextFieldDefaults.textFieldColors(focusedTextColor = getRandomColor())
)

enter image description here

If you want to avoid it you can wrap your TextField with a Composable like

@Composable
fun MyColumn(content: @Composable () -> Unit) {
    Column(
    ) {
        content()
    }
}

using:

Text(text = message)
MyColumn(){
   TextField( 
        value = text,
        onValueChange = {
            text = it
       }
   )
}

Check these great answers by Thracian for more details:

Gabriele Mariotti
  • 320,139
  • 94
  • 887
  • 841
  • how would you explain my last note about changing message to constant or stringResourse? I wrote this in the last sentences – Foenix Mar 16 '23 at 22:28