Jetpack Compose - Picplz/picplz-aos GitHub Wiki

์ œํŠธํŒฉ ์ปดํฌ์Šค

UI ๋„๊ตฌ ํ‚คํŠธ๋กœ์„œ ์„ ์–ธํ˜• ํ”„๋กœ๊ทธ๋ž˜๋ฐ ํŒจ๋Ÿฌ๋‹ค์ž„ ํŠธ๋ฆฌ ํ˜•ํƒœ๋กœ UI๋ฅผ ๊ตฌ์„ฑํ•  ์ˆ˜ ์žˆ๋‹ค


Composable๋ผ๋Š” ui ํ•จ์ˆ˜ ํ˜•ํƒœ์˜ ์œ„์ ฏ์„ ๊ณ„์ธต์ ์œผ๋กœ ๊ตฌ์„ฑ




recomposition

์ฐธ๊ณ : https://developer.android.com/develop/ui/compose/mental-model?hl=ko

compose์—์„œ ์ƒˆ๋กœ์šด ๊ฐ’์„ ์—…๋ฐ์ดํŠธํ•  ๋•Œ ๋ณ€๊ฒฝ๋˜์ง€ ์•Š์€ ํ•จ์ˆ˜๋Š” ์žฌ๊ตฌ์„ฑํ•˜์ง€ ์•Š๊ณ , ๊ตฌ์„ฑ ๊ฐ€๋Šฅํ•œ ํ•จ์ˆ˜๋ฅผ ๋‹ค์‹œ ํ˜ธ์ถœ



๋‹จ๊ณ„๋ณ„ ui ๊ตฌ์„ฑ (์ถ”ํ›„ ์ž‘์„ฑ)



composition



layout



drawing




Composable



๊ธฐ๋ณธ ํ˜•ํƒœ

Composable(
    // ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ํ†ตํ•ด ์™ธ๋ถ€์—์„œ ๊ฐ’์„ ๋ฐ›์•„์„œ ์‚ฌ์šฉํ•˜๊ฑฐ๋‚˜, ์ „์ฒด์ ์ธ ์„ค์ •์„ ๋ณ€๊ฒฝํ•  ๋•Œ ์‚ฌ์šฉ
) {
    // ํ•ด๋‹น composable ๋‚ด๋ถ€์˜ ui ๊ตฌ์„ฑ์œผ๋กœ composable๋กœ ๊ตฌ์„ฑ -> composable์˜ ํŠธ๋ฆฌ ํ˜•ํƒœ
}



Modifier

Composable์˜ ํฌ๊ธฐ, ๋ฐฐ๊ฒฝ, ์œ„์น˜, ํด๋ฆญ ์ด๋ฒคํŠธ ๋“ฑ์˜ ๊ธฐ๋ณธ ์„ค์ •

์ฒด์ธ ํ˜•ํƒœ๋กœ ์กฐํ•ฉํ•  ์ˆ˜ ์žˆ๋‹ค

.fillMaxSize() / .fillMaxWidth() / .fillMaxHeight()

์ƒ์œ„ Composable์„ ๊ธฐ์ค€์œผ๋กœ ์ตœ๋Œ€ ๊ณต๊ฐ„์œผ๋กœ ์ฑ„์šฐ๋Š” ์„ค์ •

.padding()
  • ๊ฐ€๋กœ ์„ธ๋กœ ์—ฌ๋ฐฑ์„ ์ „๋ถ€ ์ฃผ๋Š” ๊ฒฝ์šฐ -> .padding(10.dp)

  • ๊ฐ€๋กœ, ์„ธ๋กœ ๋ณ„๊ฐœ๋กœ ํ˜น์€ ํ•œ์ชฝ์—๋งŒ ์ฃผ๋Š” ๊ฒฝ์šฐ -> .padding(horizontal = 32.dp) , .padding(vertical = 32.dp)

๊ธธ์ด ๋‹จ์œ„

dp

  • Density-independent Pixels
  • ๊ธธ์ด์— ์‚ฌ์šฉ ํ™”๋ฉด ๋ฐ€๋„์— ๋”ฐ๋ผ ํฌ๊ธฐ๊ฐ€ ์กฐ์ •๋˜๋Š” ๋‹จ์œ„
  • ํ™”๋ฉด ๋ฐ€๋„์— ๋”ฐ๋ผ ์กฐ์ •๋˜๊ธฐ์— ํ•ด์ƒ๋„์— ๋งž์ถฐ์„œ ์ ์ ˆํ•œ ํฌ๊ธฐ ์„ค์ • ๊ฐ€๋Šฅ

sp

  • Scale-independent Pixels
  • ํ…์ŠคํŠธ ํฌ๊ธฐ์— ์‚ฌ์šฉ



๊ธฐํƒ€ ๊ธฐ๋ณธ ์„ค์ •๊ฐ’๊ณผ ์ผ๋ฐ˜์ ์ธ ํ™œ์šฉ๋ฒ•

Button(
    onClick = {
        viewModel.handleIntent(LoginIntent.NavigateToKaKao)
    },
    modifier = Modifier
        .fillMaxWidth()
        .padding(horizontal = 32.dp),
    colors = ButtonDefaults.buttonColors(
        containerColor = Color(0xFFFFEB3B),
        contentColor = Color.Black
    ), // color์—๋Š” ButtonDefaults.buttonColors๊ฐ์ฒด๋ฅผ ๋ฐ›์„ ์ˆ˜ ์žˆ๊ณ  ๊ทธ ์„ธ๋ถ€ ์„ค์ •์œผ๋กœ `containerColor`, `contentColor`๋“ฑ์„ ์ž…๋ ฅ ๊ฐ€๋Šฅ
    shape = RoundedCornerShape(10.dp)
) {...}

Text(
    text = "์นด์นด์˜ค๋กœ ๊ณ„์†ํ•˜๊ธฐ",
    modifier = Modifier.padding(
        vertical = 8.dp
    ),
    style = TextStyle(
        fontSize = 16.sp,
        fontWeight = FontWeight.Bold,
        color = Color(0xFF371C1D)
    ) // ํ…์ŠคํŠธ ์Šคํƒ€์ผ์€ `TextStyle` ๊ฐ์ฒด์™€ ๊ทธ ํ•˜์œ„ ํด๋ž˜์Šค ์ž…๋ ฅ์œผ๋กœ ์„ค์ • ๊ฐ€๋Šฅ
)

Composable ๋ณ„๋กœ color๋‚˜ shape๊ฐ™์€ ์„ค์ • ๋งค๊ฐœ๋ณ€์ˆ˜๋“ค์ด ์กด์žฌํ•˜๋ฉฐ, Color๋‚˜ shape ๊ฐ™์ด ์ •ํ•ด์ง„ ํ…œํ”Œ๋ฆฟ์ด ํ•„์š”ํ•œ ๊ฒฝ์šฐ์— ์ด๋ฅผ ์ œ๊ณตํ•ด์ฃผ๋Š” ๊ฐ์ฒด๋“ค์ด ์žˆ์Œ



๊ธฐ๋ณธ composable



Scaffold

์•ฑ์˜ ์ตœ์ƒ๋‹จ ๊ธฐ๋ณธ ๋ ˆ์ด์•„์›ƒ ์„ค์ • ๊ฐ€๋Šฅ

image

  • TopBar, BottomBar, Snack-Bar, fab ๋“ฑ์˜ ui ์š”์†Œ ์„ค์ • ๊ฐ€๋Šฅ
  • ํ•ด๋‹น ์•ฑ ui ์š”์†Œ๋“ค์˜ ๋ ˆ์ด์•„์›ƒ ๊ธธ์ด ๊ฐ’ ์ด์šฉ ๊ฐ€๋Šฅ
    • ์˜ˆ์‹œ) ์ƒ๋‹จ ์ƒํƒœ ๋ฐ”์˜ height ๊ฐ’์ธ innerPadding ์ด์šฉ ๊ฐ€๋Šฅ
      • ์ตœ์ƒ๋‹จ ui ์š”์†Œ์— ์ ์šฉ
      • Scaffold(
            modifier = Modifier
                .fillMaxSize(),
        ) { innerPadding ->
            Box(
                modifier = Modifier
                    .fillMaxSize()
                    .padding(innerPadding),
                contentAlignment = Alignment.Center
            ) {}
        }



Box

  • ์ž์‹ Composable์„ Stack ํ˜•ํƒœ๋กœ ์ž์œ ๋กญ๊ฒŒ ๋ฐฐ์น˜ ๊ฐ€๋Šฅ
  • ๊ฒน์ณ์„œ ๋ฐฐ์น˜ ๊ฐ€๋Šฅ
  • ๊ธฐ๋ณธ ์˜์—ญ ๊ตฌ๋ถ„์„ ํ•  ๋•Œ๋„ ์‚ฌ์šฉ
๋งค๊ฐœ๋ณ€์ˆ˜ ์˜ต์…˜

contentAlignment :

  • ์˜ˆ์‹œ : contentAlignment = Alignment.Center



Row

์ž์‹ ์ปดํฌ์„œ๋ธ”์„ ์ˆ˜ํ‰์œผ๋กœ ๋ฐฐ์น˜

๋งค๊ฐœ๋ณ€์ˆ˜ ์˜ต์…˜

horizontalArrangement : ์ˆ˜ํ‰์œผ๋กœ๋Š” ๊ฐ„๊ฒฉ ์„ค์ •

  • Arrangement๊ฐ์ฒด๋ฅผ ํ†ตํ•ด ์ž…๋ ฅ
  • ์˜ˆ์‹œ : horizontalArrangement = Arrangement.SpaceBetween

verticalAlignment: ์ˆ˜์ง์œผ๋กœ๋Š” ์œ„์น˜ ์„ค์ •

  • ์˜ˆ์‹œ : verticalAlignment = Alignment.CenterVertically



Column

์ž์‹ Composable์„ ์ˆ˜์ง์œผ๋กœ ๋ฐฐ์น˜

๋งค๊ฐœ๋ณ€์ˆ˜ ์˜ต์…˜

verticalArrangement : ์ˆ˜์ง์œผ๋กœ ๊ฐ„๊ฒฉ์„ ์„ค์ •

  • Arrangement ๊ฐ์ฒด๋ฅผ ํ†ตํ•ด ์ž…๋ ฅ
  • ์˜ˆ์‹œ : verticalArrangement = Arrangement.SpaceBetween

horizontalAlignment : ์ˆ˜ํ‰์œผ๋กœ ์œ„์น˜ ์„ค์ •

  • ์˜ˆ์‹œ : horizontalAlignment = Alignment.CenterHorizontally
  • ์—ญํ•  : Column ๋‚ด๋ถ€์˜ ์ž์‹ Composable์„ ์ˆ˜ํ‰ ๋ฐฉํ–ฅ์œผ๋กœ ์–ด๋–ป๊ฒŒ ์ •๋ ฌํ• ์ง€ ๊ฒฐ์ •ํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ์™ผ์ชฝ, ์˜ค๋ฅธ์ชฝ ๋˜๋Š” ์ค‘์•™ ์ •๋ ฌ์„ ์„ค์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.



Spacer

Spacer(modifier = Modifier.width(10.dp))

์—ฌ๋ฐฑ ์ฒ˜๋ฆฌํ•  ๋•Œ ์‚ฌ์šฉ padding/gap๊ฐ™์€ modifier ์„ค์ •์˜ ์ผ๋ถ€ ์“ธ๋ชจ์™€๋„ ๊ฒน์น˜๋Š” Composable

Composable๊ฐ„์˜ ๊ฐ„๊ฒฉ์„ ๋งŒ๋“ค๋•Œ ์‚ฌ์šฉํ•œ๋‹ค

height, width ์„ค์ •์„ ํ†ตํ•ด ๊ฐ„๊ฒฉ์„ ๋งŒ๋“ฆ




์ ์šฉ ์‚ฌ๋ก€

ํŠธ๋ฆฌ์‹ ๊ตฌ์„ฑ

Scaffold
    โ””โ”€โ”€ Button
          โ””โ”€โ”€ Row
               โ”œโ”€โ”€ Image
               โ”œโ”€โ”€ Spacer
               โ””โ”€โ”€ Text
// LoginScreen.kt
import ...

@Composable
fun LoginScreen(
    navController: NavController,
    modifier: Modifier = Modifier,
    viewModel: LoginViewModel = viewModel()
) {
    Scaffold(...) { innerPadding ->
        Box(...) {
            Button(...) {
                Row(...) {
                    Image(...)
                    Spacer(...)
                    Text(...)
                }          
            }
        }
    }
}

์ฐธ๊ณ  ๋งํฌ

โš ๏ธ **GitHub.com Fallback** โš ๏ธ