Hi Team: I am exploring the drawing/rendering me...
# compose-android
z
Hi Team: I am exploring the drawing/rendering mechanism of Compose on Android. Below is my source code:
Copy code
class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
//        enableEdgeToEdge()
        setContent {
            MyDebugTheme {
                Column {
                    MyTextField()
                    Text("Demo")
                }
            }
        }
    }
}

@Composable
fun MyTextField() {
    TextField(
        value = "",
        onValueChange = { newText ->

        },
        placeholder = { Text("Input your content") },
        modifier = Modifier.fillMaxWidth()
    )
}
I put a TextField and a Text in one Column, and only focus on the TextField to make the cursor flashed. After set debug.hwui.show_dirty_regions to 1, I saw both the TextField and the Text are redraw (refer to the video attached) ? Is it because the Column() is a inline function? And how should I change my code to only make the TextField redraw if there is no any change of the Text? Thanks a lot! Is it because the Column function is a inline function? How can I change the source code to make it only redraw the TextField without Text?
j
How many times is the "Demo" text being recomposed? You can check inside of Android Studio using the layout inspector.
z
Currently it seems that as long as the cursor keeps blinking, the entire Column will keep redrawing
c
Don’t mistake „recomposition“ with „redraw“
z
Yes, I know the different between these two concept. But it seems to me that if I set debug.hwui.show_dirty_regions to 1, does the red flashing area mean it is redrawn?
j
Yeah that is correct, but redrawing isn't necessarily bad. What you care about is the number of recompositions.
z
Actually, I am both an Android application developer and an Android Framework developer. I also focus on the code logic in frameworks/base/libs/hwui. So, I would like to know, if I can make the redraw area smaller?
s
It does sound like a bug, I would assume that text field is triggering remeasure / redraw that forces scaffold to update. We have also fixed a small issue that caused scaffold to update more than it needed a few months ago, maybe it is related. Could you try the same thing with some other layout, like a column?
In general, compose usually draws everything in a compose view, but I assume there's a certain caching point between layers to ensure only changed render nodes are updated Maybe we need to look into this more, but tbh it hasn't been a performance problem so far. We are also usually optimizing for the case of scrolling lazy layouts that take the whole screen, and everything has to be redrawn anyways with such layout. It might be annoying if the text field cursor triggers redraw of the whole screen, though, if the screen is complex enough.
As you mentioned, if I write something in a Scaffold, whole screen redraw all the time. Could you please let me know how you fix this bug? From Compose side or Android Framework side? Any link for this fix?
s
Could you try to repro this in some other layout first? I am not exactly sure if this is Scaffold exclusive. For example, do we still redraw if the text field is in a lazy (or regular) column with other items?
z
It is already mid-night in China. I am laying on my bed : ) I will do this test for you tomorrow. Once I got the test result, I will share with you in this thread.
s
Thanks, I might look into this on Monday as well
z
Thanks a lot, let discuss it tomorrow~ Have a nice day~
Hi @shikasd, sorry for late response. I change my to from Column() to LazyColumn(), and the redraw region still included both TextField and Text.
Copy code
class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
//        enableEdgeToEdge()
        setContent {
            MyDebugComposeTheme {
                LazyColumn {
                    item { MyTextField() }
                    item { MyText() }
                }
            }
        }
    }
}

@Composable
fun MyTextField() {
    TextField(
        value = "", // 绑定状态
        onValueChange = { newText ->

        },
        placeholder = { Text("Input your content") },
        modifier = Modifier
            .fillMaxWidth()
            .padding(8.dp)
    )
}

@Composable
fun MyText() {
    Text("Demo")
}
s
Thanks for checking Can you file a bug to Compose UI tracker with the above findings? I think it is expected to work this way right now, unfortunately, but maybe people want to improve this at some point