Hi Compose Team: I'm doing some research on comp...
# compose
z
Hi Compose Team: I'm doing some research on compose rendering/drawing, and I found some strange phenomena. If I use the code that Android Studio automatically generates for me, in other words, I used "Scaffold" in the code, when a redraw is required, the entire screen is refreshed. However, if I remove "Scaffold", only the areas that have changed will be redrawn. I would like to know, does this meet our expectations when designing Compose? Use "Scaffold":
Copy code
override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    enableEdgeToEdge()
    setContent {
        MyDebugTheme {
            Scaffold(modifier = Modifier) { innerPadding ->
                TextField(
                    value = "",
                    onValueChange = { newText ->

                    },
                    placeholder = { Text("Input your content") },
                    modifier = Modifier.padding(innerPadding)
                        .fillMaxWidth()
                )
            }
        }
    }
}
Remove "Scaffold":
Copy code
override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
//        enableEdgeToEdge()
        setContent {
            MyDebugTheme {
                TextField(
                    value = "",
                    onValueChange = { newText ->

                    },
                    placeholder = { Text("Input your content") },
                    modifier = Modifier.fillMaxWidth()
                )
            }
        }
    }
đź§µ 3
Attached two screenshot
c
not sure how the code you posted and the screenshot match (where is the red background coming from?) But what you see is, that the “body” of the scaffold is
fillMaxSize
and when you render just the
TextField
you added a
fillMaxWidth
modifier so only the width is maxed and the height is just the content height.
also, with the code you posted, there is nothing “redrawn” or “refreshed”
z
Thanks for your quick reply and sorry for not making it clear. I set debug.hwui.show_dirty_regions to 1, the red frame is showing the redrawed area. I change the code like below, but the redraw area is still the whole screen.
Copy code
override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    enableEdgeToEdge()
    setContent {
        MyDebugTheme {
            Scaffold { innerPadding ->
                TextField(
                    value = "",
                    onValueChange = { newText ->

                    },
                    placeholder = { Text("Input your content") },
                    modifier = Modifier.padding(innerPadding)
                        .fillMaxWidth()
                )
            }
        }
    }
}
c
I guess it’s still because the body of a scaffold is
fillMaxSize
. not sure if
debug.hwui.show_dirty_regions
is optimized for Compose. It renders to a canvas and what I imagine, the canvas is only as big as its content and what you see is the “dirty” canvas.
z
OK, let me change to another question. Source code are like below:
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. But why both the TextField and the Text are redrawed? 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?
c
Ah, so redraw is an issue from the old View world where this operation was heavy because of the layout and measuring paths that view needed. Composables work differently and redraw is not an issue any more. do some research on “Recomposition” and read this article https://developer.android.com/develop/ui/compose/mental-model
z
Yes, I have learned about Recomposition. However, I am both an Android application developer and an Android Framework developer. I also focus on the code logic in frameworks/base/libs/hwui.
Do you mean we don't need care about redraw process if we use Compose? If the redraw is larger then dirty area, won’t it cause performance loss?
c
no, because it renders directly to a canvas via https://skia.org/
z
Sorry, I am confused. In my concept, no matter we use the old View World or Compose, they will be converted into RenderNode and then drawn, isn't that right? If I'm wrong, could you please correct me? This is really important to me, thank you very much~
c
Not sure, but I think compose on android does not use any of those “view” render classes. In compose you can just render your screen to a SVG. https://github.com/chrimaeon/compose-to-svg/blob/8c89ff9135b5f667b1b4793fea4e17994[…]seApp/src/desktopMain/kotlin/com/cmgapps/compose/SvgRenderer.kt If your target is android only, you might get better answers in #C04TPPEQKEJ with a better phrased question 🙂
z
OK, got it, thank you very much for your kind answer, I will go to the #C04TPPEQKEJ to try to figure out my problem. Have a nice day~