์ปดํฌ์ง์ (Composition), ๋ ์ด์์(Layout), ๊ทธ๋ฆฌ๊ธฐ(Drawing)
- Jetpack Compose ๋ ์ ์ธํ UI ์ฝ๋๋ฅผ ํ๋ฉด์ ํฝ์ (๋ ๋๋ง๋ UI) ๋ก ๋ณํํ๊ธฐ ์ํด ์ 3๋จ๊ณ๋ฅผ ๊ฑฐ์น๋ค.
- ์ํ ๋ณ์๊ฐ ๋ฐ๋๋๋ง๋ค ๋ชจ๋ ๊ฒ์ ๋ค์ ๊ทธ๋ฆฌ๋ ๊ฒ์ด ์๋๋ผ, ์ ์ค ๊ผญ ํ์ํ ์์ ๋ง ์ํํ๋ค.
- ex. drawing ์๋ง ์ํฅ์ ์ฃผ๋ ๋ณ๊ฒฝ์ composition ๊ณผ layout ์ ์์ ํ ๊ฑด๋๋ธ ์ ์์.
- ๋ฐ๋ฉด ui ๊ตฌ์กฐ ์์ฒด๊ฐ ๋ฐ๋๋ ๊ฒฝ์ฐ์๋ ์ธ ๋จ๊ณ๊ฐ ๋ชจ๋ ํ์ํ ์ ์์.
- ๊ฐ ๋จ๊ณ๋ ์ด์ ๋จ๊ณ๊ฐ ์๋ฃ๋์ด์ผ ์งํ๋ ์ ์์ง๋ง, ๋ชจ๋ ์ํ ๋ณ๊ฒฝ์ด ์ธ ๋จ๊ณ๋ฅผ ๋ค ๊ฑฐ์น๋ ๊ฒ์ ์๋.
1. ์ปดํฌ์ง์ (Composition)
- ์ปดํฌ์ ๋ธ ํจ์๋ฅผ ์คํํ๋ฉฐ, UI ํธ๋ฆฌ๋ฅผ ๊ตฌ์ถํ๊ณ , ๋ฌด์์ ํ์ํด์ผํ ์ง๋ฅผ ๊ธฐ๋กํจ.
- @Composable ํจ์๋ค์ด ์คํ ๋จ.
- ๋จ์ํ ํธ๋ฆฌ๋ฅผ ๋ง๋๋ ๊ฒ์ ๋์ด, SlotTable ์ด๋ผ๋ ๋ฉ๋ชจ๋ฆฌ์ ์ํ๋ฅผ ์ ์ฅํ๊ณ ์ด์ ๊ณผ ๋น๊ต(Diffing) ํ๋ ๊ณผ์
์ปดํฌ์ ๋ธ(Composable) ํจ์ : UI ๋ฅผ ๊ตฌ์ฑํ๋ ํจ์๋ก @Composable ์ด๋ ธํ ์ด์ ์ด ๋ถ์ผ๋ฉฐ UI ๋ฅผ ์ ์ธํจ
์ด๋ ธํ ์ด์ ์ฌ์ฉ ๊ธฐ์ค ๋ฐ ํน์ง
1) UI ์์ (์: Text, button, cloumn, row ๋ฑ)
2) ๋ค๋ฅธ ์ปดํฌ์ ๋ธ์ ํฌํจํ๋ ํจ์์ ๋ถ์ฌ์ ์ฌ์ฌ์ฉ ๊ฐ๋ฅํ UI ์์
3) ํ๋ฉด์ ๋ฌด์ธ๊ฐ๋ฅผ "๊ทธ๋ฆฌ๊ธฐ ์ํ ์ ๋ณด" ๋ฅผ ์ ๊ณตํ๋ค๋ฉด ๋ฌด์กฐ๊ฑด @Composable ์ ๋ถ์ฌ์ผ ํจ.
4) ์ด๋ ธํ ์ด์ ์ด ๋ถ์ ํจ์๋ค์ ์ปดํฌ์ง์ ๋จ๊ณ์์ ์คํ๋์ด UI ํธ๋ฆฌ(๋ ธ๋) ๋ฅผ ๊ตฌ์ถํจ.
5) ์ํ(state) ๋ณํ์ ๋ฐ๋ผ ๋ค์ ์คํ(restart) ๋์ด์ UI ๊ฐฑ์ (์ฌ์ปดํฌ์ง์ ) ํด์ผ ํ๋ค๋ฉด, @Composable ๋ถ์ด์ผ ํจ.
- ๋ด ํ๋ก์ ํธ ์์(feat. ๋ก๊ทธ์ธ ๋๋ฉ ํ๋ฉด)

- ์ ๋์ด๋ ๊ธฐ์ค์ ๋ณด๋ฉด์ ๋ด๊ฐ ๊ตฌํํ ์ฝ๋๋ฅผ ๋ค์ ๋ณด์๋ค
- ์ฅ๊ธฐ์ ์ผ๋ก ๋ดค์๋ ๋นํจ์จ์ ์ธ ๋ถ๋ถ์ด ๋ง์๋ค
- ํ์ฌ ์ฝ๋ : ๋ก๊ทธ์ธ ๋๋ฉ ํ๋ฉด์์ @Composable ์ ์ธ๋ ๋ถ๋ถ์ ์๋์ ๊ฐ์.
// 1. ์ ์ฒด ํ๋ฉด ์์ฒด (screen level)
@Composable
fun LoginLandingScreen( // ์ด๋ฒคํธ ํธ์ด์คํ
(Event Hoisting), ํจ
onKakaoLogin: () -> Unit,
onGoogleLogin: () -> Unit,
onEmailStart: () -> Unit,
onHomeClick: () -> Unit, // ์์ ํ๋ฒํผ
onDashboardClick: () -> Unit // ์์ ๋์๋ณด๋ ๋ฒํผ
) {
Column(modifier = Modifier.fillMaxSize().background(Color.White)) {
// ์๋จ/ํ๋จ ๋ ์ด์์ ๋ฐฐ์น ๋ก์ง...
SocialLoginButton(text = "๋๋ ์ด๋ฉ์ผ๋ก ์์ํ๊ธฐ", onClick = onEmailStart)
// ...
}
}
// 2. ๋ก๊ทธ์ธ ๋ฒํผ (component level - ์ฌ์ฉ์ฑ)
@Composable
fun SocialLoginButton(
text: String,
onClick: () -> Unit
) {
Button(
onClick = onClick,
modifier = Modifier
.fillMaxWidth()
.height(56.dp), // ํผ๊ทธ๋ง์ ๋ํฐํ ๋ฒํผ ๋์ด
shape = RoundedCornerShape(28.dp), // ์์ฃผ ๋ฅ๊ทผ ์์ฝ ๋ชจ์
colors = ButtonDefaults.buttonColors(
containerColor = Color.White,
contentColor = Color.Black
),
elevation = ButtonDefaults.buttonElevation(defaultElevation = 0.dp)
)
// 3. ํ๋ฆฌ๋ทฐ (๊ฐ๋ฐ ๋๊ตฌ)
@Preview(showBackground = true, showSystemUi = true)
@Composable
fun LoginLandingScreenPreview() {
AuriTheme() {
LoginLandingScreen(
onKakaoLogin = {},
onGoogleLogin = {},
onEmailStart = {},
onHomeClick = {}, // ์์ ํ๋ฒํผ
onDashboardClick = {}) // ์์ ๋์๋ณด๋ ๋ฒํผ
}
}
- ๋ด๊ฐ ์์ฑํ ์ฝ๋๋ ํผ์งํ ๊ธฐ๋ฅ ๋จ์๋ก ๋๋ ์ ธ์๋ค. ์ ์ด์ ๊ธฐ๋ฅ์ด ๋ฒํผ ๋ช๊ฐ๋ฟ์ธ ํ๋ฉด์ด๋ผ ....
- ๋ก๊ทธ์ธ ๋ฒํผ(๊ณตํต) ์ ์ฌ์ฌ์ฉํ๋ ๊ฒ์ฒ๋ผ ์ฌ์ฌ์ฉ์ฑ๊ณผ, ์ต์ํ์ ์ฌ์ปดํฌ์ง์
์ ๋ค๋ฐฉ๋ฉด์ผ๋ก ๊ณ ๋ คํ์ฌ @Composable ๋จ์๋ก ๋ถ๋ฆฌํ๋ ๊ฒ์ด ์ข๋ค.
- ์ฌ์ฌ์ฉ์ฑ : ์ฌ๋ฌ ํ๋ฉด์์ ์ฐ์ด๋ ๋ฒํผ, ํ ์คํธ ์คํ์ผ ๋ฑ
- ์ฑ๋ฅ ์ต์ ํ : ํ๋ฉด ์ ์ฒด๊ฐ ์ฌ์ปดํฌ์ง์ ๋๋ ๊ฒ์ ๋ง๊ธฐ ์ํด, ์์ฃผ ๋ฐ๋๋ ๋ถ๋ถ๋ง ๋ณ๋์ @Composable ํจ์๋ก ๋ถ๋ฆฌํ๋ค๊ณ ํจ.
- ์ฌ์ค์ ์๋ณด๋ค ๋ ์ธ๋ฐํ๊ฒ ์ปดํฌ์ ๋ธ ๋จ์๋ฅผ ๋๋๋ ๊ฒ์ด ์ข๋ค
๊ฐ์ ํ ๋งํ ๋ถ๋ถ
1. ๋ฒํผ
- ํ์ฌ ๋ก๊ทธ์ธ ๋ฒํผ์ ๊ฒฝ์ฐ, ๋์ด 56.dp, pill ๋ชจ์ 28.dp ๋ผ๋ ๋์ผํ ๋ ์ด์์ ์ ์ฝ์ ๊ฐ์ง๊ณ ์๋ค.
- ๋ง์ฝ ๋์ค์ ๋ฒํผ ๋์ด๋ฅผ ์กฐ์ ํ๊ฒ ๋์๋ ์ธ ๊ตฐ๋ฐ ์ฝ๋๋ฅผ ๋ชจ๋ ์์ ํด์ผ ํ๋ค. ์ด๋ ๋ ์ด์์ ๋จ๊ณ ์ ์ง๋ณด์ ํจ์จ์ ๋จ์ด๋จ๋ฆฐ๋ค.
- ๋ฒํผ ๊ฐ์ ๋ฐฉ์: Auri base button ์ด๋ผ๋ ๊ณตํต ์ปดํฌ๋ํธ๋ฅผ ๋ง๋ค๊ณ "๊ทธ๋ฆฌ๊ธฐ(drawing)" ์์(๋ก๊ณ , ๋ฐฐ๊ฒฝ์, ํ ์คํธ) ๋ง ํ๋ผ๋ฏธํฐ๋ก ๋ฐ๊ฒํ๋ค.
- ํ์ฌ ๊ณตํต ui component ๊ฒฝ๋ก : ui/core/componenets
2. ์คํฌ๋ฆฐ ๋ผ๋ ๊ตฌ์กฐ
- ๋ํ ํ์ฌ LoginLandingScreen ์ด๋ผ๋ ๊ฑฐ๋ํ ํจ์ ์์ ๋ชจ๋ ๋ฒํผ์ด ๋ค์ด์๋ ๊ตฌ์กฐ์ด๋ค. ์ ์ด๋ ๊ฒ ์งฐ์ง?
- ๋ฐ์ํ ์ ์๋ ์ผ: ๋ง์ฝ ๋ฒํผ ํ๋์ "๋ก๊ทธ์ธ ์ค" ์ด๋ผ๋ ๋ก๋ฉ ์ํ๊ฐ ์ถ๊ฐ๋์ด์ text ๊ฐ์ด ๋ฐ๋๋ฉด, ๋ถ๋ชจ์ธ LoginLandingScreen ์ ์ฒด๊ฐ ์ฌ์ปดํฌ์ง์ ๋์์ด ๋ ์ ์๋ค.
- ์คํฌ๋ฆฐ ๊ฐ์ ๋ฐฉ์: ๊ฐ ๋ฒํผ์ ๋ณ๋์ @Composable ํจ์๋ก ์์ ํ ๋ ๋ฆฝ ์ํค๋ฉด, Composer ๋ slot table ์ ํ์ธํ์ฌ ์ ๋ ฅ ๊ฐ์ด ๋ณํ์ง ์์ ๋ค๋ฅธ ๋ฒํผ๋ค์ skipToGroupEnd() ๋ฅผ ํตํด ์คํ ๊ฑด๋๋ธ ์ ์๋ค.
2. ๋ ์ด์์ (Layout)
- ์์ฑ๋ ํธ๋ฆฌ๋ฅผ ๋ฐํ์ผ๋ก ๊ฐ ์์์ ํฌ๊ธฐ์ ์์น๋ฅผ ๊ฒฐ์ ํจ.
- ์ปดํฌ์ง์ ์์ ์์ฑ๋ ํธ๋ฆฌ๋ฅผ ๋ฐํ์ผ๋ก, ๊ฐ ๋ ธ๋์ ํฌ๊ธฐ(measure)๋ฅผ ์ธก์ ํ๊ณ ํ๋ฉด ์์ ์ขํ(place)๋ฅผ ๊ฒฐ์ ํ๋ ๊ณผ์ .
- ์ฆ, ui ์์๋ฅผ ์ด๋์, ์ผ๋ง๋ ํฌ๊ฒ ๊ทธ๋ฆด์ง ๊ฒฐ์ ํ๋ค.
- ์ ์ฝ ์กฐ๊ฑด(Constraints)
- ๋ถ๋ชจ column ์ด ์์ ๋ฒํผ์๊ฒ ์ ์ฝ์ ๊ฑธ ์ ์์
- ์: ๊ฐ๋ก, ์ธ๋ก ์ต๋์ต์ ๊ธธ์ด
- ๊ฐ์ค์น ๊ณ์ฐ
- ๊ฐ๊ฒฉ ๋ฐฐ์น
- ๊ธฐ์กด Android View ์์ ์ฐจ์ด์ Single Pass Measurement (๋จ ํ๋ฒ์ ์ธก์ )
- Jetpack Compose์ ๋ ์ด์์์ ๋จ ํ ๋ฒ์ ์ธก์ (Single Pass)๋ง์ผ๋ก ๋ชจ๋ ์์์ ํฌ๊ธฐ๋ฅผ ๊ฒฐ์ ํ๋๋ก ์ค๊ณ๋์ด ์์.
- ๊ธฐ์กด ์๋๋ก์ด๋ view ์์คํ
์ด ๋ณต์กํ ๊ณ์ธต ๊ตฌ์กฐ์์, ํ ํ๋ ์ ์์์๋ on measure ์ ์ฌ๋ฌ๋ฒ ํธ์ถ ์ฑ๋ฅ ์ ํ๋ฅผ ์ผ์ผ์ผฐ์์ผ๋ "๋จ๋ฐฉํฅ ์ ์ฝ ์กฐ๊ฑด ์ ๋ฌ(Constraints flow down, Sizes return up)" ๋ฐฉ์์ผ๋ก ํด๊ฒฐํจ
- (์์ component ์ธก์ , ๊ทธ ๊ฒฐ๊ณผ๋ฅผ ํ ๋๋ก ๋ถ๋ชจ ์ธก์ , ์์์๊ฒ ์ต์ข ํฌ๊ธฐ ํต๋ณด ๋ฑ๋ฑ ... )
- ์ด ๊ท์น ๋๋ถ์ UI ๊ฐ ์๋ฌด๋ฆฌ ๊น๊ฒ ์ค์ฒฉ๋์ด๋ ์ฑ๋ฅ์ด ์ผ์ ํ๊ฒ ์ ์ง๋จ.
- Modifier ํํฐ
- ๋จ์ํ ์์ฑ์ ์ฃผ๋ ๊ฒ์ด ์๋๋ผ, ๋ถ๋ชจ๋ก๋ถํฐ ์จ ์ ์ฝ ์กฐ๊ฑด(constraints) ์ ์์์๊ฒ ์ ๋ฌํ๊ธฐ ์ ์์ ํ๋ ํํฐ ์ญํ ์ ํจ.
- ๊ทธ๋ ๋ค๋ฉด ์ต์์ column์ ์์นํ modifier ์ "๋ถ๋ชจ"๋?
- ์๋๋ก์ด๋ ์์คํ ์ฐฝ
- ์ ์ฝ ์กฐ๊ฑด ์์ : "๋๋ ๊ฐ๋ก 0~1080px, ์ธ๋ก 0~2400px(ํฐ ํด์๋) ์ฌ์ด์์ ๋ค ํฌ๊ธฐ๋ฅผ ๊ฒฐ์ ํด"
- ๋ถ๋ชจ column ์ด ์์ ๋ฒํผ์๊ฒ ์ ์ฝ์ ๊ฑธ ์ ์์
Column(
// ์ ์ฒด ํ๋ฉด
modifier = Modifier
.fillMaxSize()
.background(Color.White),
3. ๊ทธ๋ฆฌ๊ธฐ (drawing)
- ์์น๊ฐ ์ ํด์ง ์์๋ค์ ์ค์ ํ๋ฉด์ ํฝ์ ๋ก ๋ ๋๋งํจ.
- ์ฆ, ์ค์ ํ๋ฉด์ ์์ ์น ํ๊ณ ์ด๋ฏธ์ง๋ฅผ ์ฌ๋ฆฌ๋ ๋จ๊ณ
- ex. ๋ถํฌ๋ช ๋ ์ ๋๋ฉ์ด์ ๊ตฌํ์, ํฌ๋ช ๋๊ฐ ๋ฐ๋๋๋ง๋ค 3๋จ๊ณ๋ฅผ ์ ๋ถ ๊ฑฐ์น๋ ๊ฒ์ด ์๋๋ผ, ๊ทธ๋ํฝ ๋ ์ด์ด(GraphicsLayer) ๋ฅผ ํตํด ๊ทธ๋ฆฌ๊ธฐ ๋จ๊ณ๋ง ํธ๋ฆฌ๊ฑฐํจ. ์๋ํ๋ฉด ๋ถํฌ๋ช ๋๊ฐ ํธ๋ฆฌ์ ๊ตฌ์กฐ or ์์น์ ์ํฅ์ ๋ฏธ์น๋ ๊ฒ์ด ์๋๊ธฐ ๋๋ฌธ
- ๊ทธ๋ํฝ ๋ ์ด์ด (GraphicsLayer)
- ๊ฐ๋ : ํ๋ฉด์ ํน์ ์์๋ฅผ ๋ณ๋์ ๋ ์ด์ด์ ๊ทธ๋ ค๋๋ ๊ฒ
- ๋ด ํ๋ก์ ํธ ์ ์ฉ ์์ : ์ฑ๋ด์ ์์ฑ ์ธ์ ์์ด์ฝ์ด ๋ถ๋๋ฝ๊ฒ ๊น๋นก์ด๋ ์ ๋๋ฉ์ด์
์ ๋ฃ๊ณ ์ ํ ๋
- ์ผ๋ฐ ๋ฐฉ์ : ๋งค๋ฒ ์ปดํฌ์ง์ ๋ถํฐ ๋ค์ ์์ํจ = ์ฌ์ฉ์ ๊ธฐ๊ธฐ ๋ฐ์ด ๋ฐ์
- GraphicsLayer ๋ฐฉ์ : Modifier.graphicsLayer { alpha = ... }๋ฅผ ์ฌ์ฉ = ์ด๋ฏธ ๊ทธ๋ ค์ง ํฌ๋ช ๋ ์กฐ์ ๋ง ํ๋ฉด ๋๊ธฐ ๋๋ฌธ์, ๋ ์ด์์๊ณผ ์ปดํฌ์ง์ ์ ๊ฑด๋๋ฐ๊ณ gpu ๊ฐ ๊ทธ๋ฆฌ๊ธฐ ๋จ๊ณ๋ง ๋ด๋นํ ์ ์์.
- ํ์ฌ ์์ฑ ์ฑ๋ด ํ๋ก์ ํธ์์ ์ ์ฉํ ๋งํ ๋ถ๋ถ : ์์ฑ ์ธ์ ์๊ฐํ ์ ๋๋ฉ์ด์ ๋์ ์, graphicsLayer์ scale๊ณผ alpha๋ฅผ ์กฐ์ ํ์ฌ ์ผ๋ ์ด๋ ์ ๋๋ฉ์ด์ ์ ๋ถ๋๋ฌ์ด ์์ง์์ ๊ตฌํํ ์ ์๋ค.
- ๊ฐ์ธ ๊ณต๋ถ๋ฅผ ์ํด ๊ธฐ๋ก๋์์ต๋๋ค.
- ์๋ชป๋ ์ ๋ณด์ ๋ํ ํผ๋๋ฐฑ ํ์ํฉ๋๋ค