
fromm μ±ν 리λ΄μΌ: UI νΉμ±μ κ³ λ €ν Compose μ»΄ν¬λνΈ μ€κ³

- #Android
- #Compose
- #Jetpack
- #Component
λ€μ΄κ°λ©°
μλ νμΈμ, λ Έλ¨Έμ€ Android νμ μμμ§μ λλ€. μ§λ 2μ, μ ν¬ νμ μμλκ»μ μ±ν 리λ΄μΌ: MVI λμ λ° μ±λ₯ κ°μ μ΄λΌλ ν¬μ€νΈλ₯Ό ν΅ν΄ 2024λ νλ°κΈ°λΆν° μ¬ν΄ μ΄κΉμ§ μ§νν μ±ν μμ€ν μ λκ·λͺ¨ κ°μ μμ μ μκ°ν΄μ£Όμ ¨μ΅λλ€.
νλ²μ μ΄ κΆκΈνμ λΆλ€μ π [fromm μ±ν 리λ΄μΌ: MVI λμ λ° μ±λ₯ κ°μ ] λ°λ‘ κ°κΈ°
μ λ μ΄λ² μ±ν 리λ΄μΌ μμ μμ UI λ μ΄μ΄ μμ μ μ£Όλ‘ λ§‘μ μ§ννμ΅λλ€. μλ‘ μμ±ν Compose UI μ»΄ν¬λνΈ μ½λλ§ ν΄λ 5000μ€μ΄ λμ μ λλ‘ μ±ν κΈ°λ₯μ μλΉν ν° λ²μμ μμ μ΄μμ΅λλ€. λν, μ±ν 리λ΄μΌ νλ‘μ νΈμ λͺ©μ μ΄ μ μ§λ³΄μμ κΈ°λ₯ νμ₯μ μ©μ΄νκ² νκΈ° μν¨μ΄μκΈ° λλ¬Έμ UI μ»΄ν¬λνΈ λν κ·Έ λͺ©μ μ μΆ©μ‘±νκ³ μ νμ΅λλ€. μ€λμ μμ κΈμμ λ―Έμ² λ€λ£¨μ§ λͺ»νλ Jetpack Compose λ§μ΄κ·Έλ μ΄μ κ³Όμ μμμ κ³ λ―Όλ€μ 곡μ ν΄λ³΄λ € ν©λλ€.
1. Slot API μ κ·Ή νμ©νκΈ° β λΆν 쑰립μ UI ꡬμ±
frommμμ μν°μ€νΈ λΆλ€μ λ€μν νμ μ λ©μμ§λ₯Ό λ³΄λΌ μ μμ΅λλ€.
π€« μν°μ€νΈ λΆλ€μ νλΌμ΄λΉ λ©μμ§λ₯Ό 보νΈνκΈ° μν΄ λ³Έ ν¬μ€νΈμ 첨λΆλ λ©μΈμ§λ€μ κ°λ° νκ²½ μν°μ€νΈμ μΊ‘μ³λ³ΈμΌλ‘ λ체ν©λλ€. κ°λ° νκ²½ μν°μ€νΈκ° λꡬλκ³ μ? λ°λ‘ μ λλ€ γ
μ΄λ―Έ λμΉ μ±μ λΆλ€λ κ³μκ² μ§μ? λ€λ₯Έ νμ μ λ©μμ§λλΌλ λμΌν ꡬ쑰λ₯Ό κ°μ§λ λΆλΆμ΄ μμ΅λλ€. μ λ λ©μμ§ UIλ€μ μλμ κ°μ΄ ꡬ쑰ν νμ΅λλ€.
κ·Έλμ Jetpack Composeμ Slot API κ°λ μ μ κ·Ή νμ©ν΄ κ³΅ν΅ UI ꡬ쑰λ₯Ό λ§λ€κ³ , κ° νμ λ³λ‘ μ°¨μ΄ λλ λΆλΆλ§ λΌμ λ£λ λ°©μμΌλ‘ 쑰립νμ΅λλ€. μ€μ λ‘ μ±ν 리λ΄μΌ μ΄ν νΉμ λΆλΆμ UI λ³κ²½μ΄ μκ²Όμ λ, μ΅μνμ μμ μΌλ‘λ λ€μν νμ μ μΌκ΄ μ μ©λμ΄ μμ μκ°μ΄ λ¨μΆλμμ΅λλ€. κ·Έλ¦¬κ³ μλ‘μ΄ λ©μμ§ νμ μ΄ μκ²Όμ λμλ, κ·Έμ λΉμΉΈμ λ€μ΄κ° μ»΄ν¬λνΈλ§ μλ‘ μ§μ 쑰립νκΈ°λ§ νλ©΄ λμ΄μμ΅λλ€.
λ¬Όλ‘ λ¨μ λ μμμ΅λλ€. μ»΄ν¬λνΈλ₯Ό μκ² λλλ€ λ³΄λ μ»΄ν¬λνΈμ depthκ° κΉμ΄μ‘κ³ , λλ²κΉ μ΄λ Preview μμ μ΄ μ‘°κΈ λ²κ±°λ‘μμ§κΈ°λ νμ΅λλ€. μ€μ λ‘ βμ±ν λ°© κΈμ¨ ν¬κΈ°β μ΅μ μ μ€κ° μ»΄ν¬λνΈμλ λ΄λ¦¬κ³ , μ€μ μ¬μ©νλ νμ μ»΄ν¬λνΈμ λ΄λ¦¬μ§ μμ κ²μ μμμ±μ§ λͺ»ν μ€μλ ν λ² νμ΅λλ€.
νμ§λ§ ꡬ쑰μ μΈ μ΄μ μ΄ ν¨μ¬ ν¬κ² λκ»΄μ‘κΈ° λλ¬Έμ ꡬ쑰λ₯Ό λ°κΎΈκΈ° 보λ€λ λ¨μ μ μμν μ μλ λ°©λ²μ κ³ λ―Όνμ΅λλ€.
2. CompositionLocal β νΉμ λ²μμ μμμ μΌλ‘ λ°μ΄ν° μ λ¬
fromm μ±μμλ μ±ν
λ°©μ βν
λ§βλ₯Ό μ μ©ν μ μμ΅λλ€. ν
λ§λ₯Ό μ μ©νλ©΄ μ±ν
λ°© λ°°κ²½, λ©μμ§ λ°°κ²½, λ©μμ§ ν
μ€νΈ λ± λ€μν μμμ μμμ΄ λ³κ²½λ©λλ€.
μ²μμλ ν
λ§ μμ±λ€μ μμ μ»΄ν¬μ λΈμμ νμλ‘ μ€μ€μ΄ νλΌλ―Έν°λ‘ λκΈ°κ³ μμμ΅λλ€.
μ»΄ν¬λνΈκ° κ²Ήκ²Ήμ΄ μΈμΈ ννμ΄λ€λ³΄λ, μ§μ μ¬μ©νλ κ°μ΄ μλμλ νμλ‘ λκΈ°κΈ° μν΄ λ°λ μ»΄ν¬λνΈλ λ€μ μ‘΄μ¬νμ΅λλ€.
κ·Έλ¦¬κ³ ν
λ§λ‘ μΈν΄ νλΌλ―Έν°μ κ°μκ° λ§μμ‘κΈ° λλ¬Έμ μ»΄ν¬λνΈμ κ°λ
μ±λ λ¨μ΄μ‘μ΅λλ€.
μλ λμλμ κ°μ νμμ΄ λ°μ λ©μμ§/λ³΄λΈ λ©μμ§
* ν
μ€νΈ/μ¬μ§/λμμ/μμ±λ©μμ§/+@
= μ½ 10κ°μ§κ° λλ μ»΄ν¬λνΈμμ λ°λ³΅λλ κ²μ
λλ€.
μ¬κΈ°μ μ νν ν΄λ²μ΄ λ°λ‘ CompositionLocalμ΄μμ΅λλ€.
CompositionLocal
μ μμμ μΌλ‘ μ»΄ν¬μ§μ
μ ν΅ν΄ λ°μ΄ν°λ₯Ό μ λ¬νλ λꡬμ
λλ€.
μμμ μΌλ‘ κ°μ²΄λ₯Ό μ λ¬νκΈ° λλ¬Έμ λ¨μ©νκ² λλ€λ©΄ CompositionLocal
μ μ»΄ν¬μ λΈμ λμμ μΆλ‘ νκΈ° μ΄λ ΅κ² λ§λ€ μ μμ΅λλ€.
μ€μ λ‘ κ³΅μ λ¬Έμμμλ CompositionLocal
μ¬μ© μ¬λΆλ₯Ό κ²°μ νλ κ°μ΄λ νλͺ©κΉμ§ μ‘΄μ¬ν©λλ€. μ±ν
λ°© ν
λ§ μ μ© μλ리μ€κ° μ λ§λ‘ μ ν©νμ§ νλ² μ κ²ν΄λ³΄κ² μ΅λλ€.
β λ§€κ°λ³μκ° ν¬λ‘μ€ μ»€ν μ΄κ³ ꡬνμ μ€κ° λ μ΄μ΄κ° κ·Έ μ‘΄μ¬λ₯Ό μΈμν΄μλ μ λλ κ²½μ° π μ§κΈ λ¬Έμ μν©κ³Ό λκ°μ
β μ μ ν κΈ°λ³Έκ°μ΄ μμ΄μΌ ν¨ π ν λ§ μμ λ―Έμ§μ μ, κΈ°λ³Έ μμμ μ μ©νλ κ·μΉμ΄ μμ
β μ μ¬μ μΌλ‘ μΌλΆ νμ μμκ° μλ λͺ¨λ νμ μμμμ μ¬μ©ν μ μμ λ μ ν© π μ±ν λ°© λ΄ μ»΄ν¬λνΈμ 90%μ ν λ§κ° μ μ©
λ°λΌμ μ λ CompositionLocal
μ΄ ν΄λ²μΌλ‘ μ ν©νλ€ νλ¨νμ΅λλ€.
val LocalChatThemeColors: ProvidableCompositionLocal<ChatThemeColors?> = compositionLocalOf { null }
//...
CompositionLocalProvider(
LocalChatThemeColors provides state.chatTheme?.toChatThemeColors()
) {
FanChatRoomContent()
}
μ±ν
λ°© κ³μΈ΅ κ΅¬μ‘°κ° μμλλ Screen μ»΄ν¬λνΈμμ CompositionLocal
μΈμ€ν΄μ€μ ν
λ§ μμ κ°μ κ°μ§ κ°μ²΄λ₯Ό λ°μΈλ© νμ΅λλ€.
μ΄μ μ€κ° μ»΄ν¬λνΈμμ νλΌλ―Έν°λ₯Ό μ λ¬νμ§ μκ³ , μ€μ λ‘ ν
λ§ μμ κ°μ΄ μ μ©λλ κ³³μμ μμμ μΌλ‘ νλ₯΄λ μ±ν
λ°© ν
λ§ κ°μ²΄λ₯Ό μ·¨λνμ¬ μμμ μ μ©ν μ μμ΅λλ€.
νμ§λ§ μ μ©νκ³ λ ν, λ κ³ λ―Όν΄μΌ ν μ§μ μ λ°κ²¬νμ΅λλ€.
μ²μμ 무μ¬μ½ μ¬μ©νλ€λ³΄λ μ΄λμμ νμ μ»΄ν¬λνΈμμ κ°μ CompositionLocal.current
λ‘ λ°λ‘ κΊΌλ΄ μ°κ³ μκ³ , λ μ΄λμμλ μμ μ»΄ν¬λνΈμμ νμ μ»΄ν¬λνΈλ‘ νλΌλ―Έν°λ‘ λ겨μ μ¬μ©νκΈ°λ νμ΅λλ€.
μΌκ΄μ± μμ΄ μ¬μ©νλλ μ΄λμμ κ°μ λλ½ν΄λ μμμ±κΈ°λ νλ€λΏλλ¬, λλ½μν¨ λΆλΆμ μ°Ύλ κ²λ μΌμ΄μμ΅λλ€. μμμ λ§ν depthκ° κΉμ μ»΄ν¬λνΈμ λλ²κΉ
μ΄ νλ€λ€λ λ¨μ μ΄ λμ± κ°ν΄μ Έ λ²λ¦° κ²μ
λλ€.
κ·Έλμ κ·μΉμ μ νμ΅λλ€:
- μ€μ μ¬μ©νλ κ°μ₯ νμ μ»΄ν¬λνΈμμ
CompositionLocal.current
λ₯Ό νΈμΆνλ - Previewμ UI Testλ₯Ό μν΄ μΈλΆμμ νλΌλ―Έν°λ‘λ λ°μ μ μκ² μ΄μ΄λ κ².
@Composable
internal fun ReceivedBubbleBox(
//...
color: Color = FrommTheme.colors.surfaceBasic03,
content: @Composable () -> Unit
) {
Box(
modifier = modifier
.background(color = LocalChatThemeColors.current?.receivedMessageBackground ?: color,),
content = {
content()
}
)
}
μ΄λ κ² κ·μΉμ μ νμ¬ μ μ©νλ μ€μκ° λ°©μ§λκ³ , λλ²κΉ λ μ©μ΄ν΄μ‘μ΅λλ€. νΉμ μμμ΄ μ μ©λμ§ μμλ€? κ·Έλ¬λ©΄ κ·Έ μμμ΄ μ μ©λμ΄μΌ νλ μ»΄ν¬λνΈμμ λΉΌλ¨Ήμκ² λΆλͺ ν΄μ‘μΌλκΉμ. μ λ¨λ½μμ μΈκΈν μ€μμΈ βμ±ν λ°© κΈμ¨ ν¬κΈ°β μ΅μ λν μ±ν λ°© ν λ§μ λκ°μ μ±κ²©μ κ°μ‘κΈ° λλ¬Έμ κ°μ λ°©μμ μ±νν¨μΌλ‘μ κ°μ νμ΅λλ€.
3. LazyColumn ꡬμμΆκΈ° β μ€ν¬λ‘€κ³Όμ μ μ
reverseLayout
κ²°λ‘ λΆν° λ§νμλ©΄, LazyColumn
μ reverseLayout μ΅μ
μ μ£Όμ΄ κ±°κΎΈλ‘ μ¬μ©νμ΅λλ€.
βμ±ν
βμ΄λΌλ κΈ°λ₯μ νΉμ§μ μ μκ°ν΄λ΄
μλ€. λ³΄ν΅ μ±ν
μ ν λ κ°μ₯ μ€λ 머무λ λΆλΆμ μ΄λμΌκΉμ? λ°λ‘ μ΅μ λ©μμ§κ° μλ λΆλΆμ
λλ€.
κ·Έλ λ€λ©΄ μ΅μ λ©μμ§λ μ΄λμ μμκΉμ? λ°λ‘ 리μ€νΈμ μ μΌ μλ«μͺ½μ
λλ€!
μ²μμλ LazyColumn
κΈ°λ³Έ μ€μ μΌλ‘ κ°λ°μ νμ΅λλ€. 리μ€νΈμ μ€λ¦μ°¨μμΌλ‘ λ©μμ§λ₯Ό λ£κ³ , 리μ€νΈ λ§μ§λ§μ μ΅μ λ©μμ§λ₯Ό μΆκ°νλ ννμ΄μ§μ.
κ°λ°μ νλ©΄μ μ¬λ¬ λ¬Έμ μ λΆλͺνκ³ μ±ν
μ νΉμ±μ λν΄ κ³ λ―Όν΄λ³΄μμ΅λλ€. κ·Έλ reverseLayoutμ μ μ©ν΄λ³΄λ©΄ μ΄λ€κ° νλ μκ°μ΄ μ€μ³μ§λκ°μ΅λλ€.
domain λ μ΄μ΄μμλΆν° λ©μμ§λ₯Ό λ΄λ¦Όμ°¨μμΌλ‘ κ°μ Έμ¬ μ μλλ‘ λκ·λͺ¨ μμ μ ν΄μΌλ§ νμ§λ§ μ΄μ μ΄ λ ν¬λ€κ³ μκ°νμ¬ ν λ€μ§μ΄ λ²λ Έμ΅λλ€.
κ·Έλμ μ΄λ€ μ΄μ μ΄ μμλκ³ μ?
μ μ₯ μ μ€ν¬λ‘€μ΄ μμ°μ€λ½λ€
- μ±ν λ°© μ§μ μ, μ΅μ λ©μμ§ λ¦¬μ€νΈλ₯Ό κ°μ Έμ΅λλ€. μ΄λ 100κ°λ₯Ό κ°μ Έμ¨λ€κ³ κ°μ νλ€λ©΄?
- before
- μ§μ κ³Ό λμμ κ°μ₯ μ΅μ λ©μμ§μΈ 100λ²μ§Έ λ©μμ§μΌλ‘ μ€ν¬λ‘€ μ΄λ
- μκ°μ μΌλ‘ μ΄κΈ° μ€ν¬λ‘€μΈ 1λ²μ§Έ λ©μμ§μμ 100λ²μ§Έ λ©μμ§λ‘ λ컀λ©! μ€ν¬λ‘€μ΄ λ³νλ λͺ¨μ΅μ΄ λμ 보μ
- after
- κ°μ₯ μ΅μ λ©μμ§λ 1λ²μ§Έ λ©μμ§
- μ€ν¬λ‘€ νμ§ μμλ μ΄λ―Έ μ΅μ λ©μμ§κ° μ΅νλ¨μ μμΉ
μ λ©μμ§ μμ μ μ€ν¬λ‘€ λΆλ΄ κ°μ
- before
- μ λ©μμ§ μμ μ, μλλ‘ μ€ν¬λ‘€μ λ°μ΄μΌ ν¨
- μ΅μ λ©μμ§μ λμ΄κ° λμ΄λλ μΌμ΄μ€κ° μμ. μ΄λ λμ΄λ λ§νΌ νλ¨μ λ©μμ§κ° μλ € 보μ΄κΈ° λλ¬Έμ λ μ€ν¬λ‘€μ λ°μ΄μΌ ν¨
- after
- 1λ²μ§Έ λ©μμ§κΉμ§ λ΄λ €κ° μλ μνλΌλ©΄ κ·Έλλ‘ μ€ν¬λ‘€μ μ μ§νλ©΄ λ¨
- μ΅μ λ©μμ§μ λμ΄κ° λμ΄λλ μμͺ½μΌλ‘ λ°λ¦¬κΈ° λλ¬Έμ μ€ν¬λ‘€ μ κ²½ μΈ νμκ° μμ΄μ§
μ¬μ©μ μ‘μ μ²λ¦¬ κ°κ²°ν
- μ±ν λ°©μ λ©μμ§ μ μ‘, FAB λ²νΌμΌλ‘ μ΄λ λ±μ μ‘μ μΌλ‘ μ΅νλ¨ μ΄λμ΄ μμ£Ό μΌμ΄λλ νκ²½μ λλ€.
- before
- μ΅μ λ©μμ§λ‘ μ΄λμ, 리μ€νΈμ μλ μ΄ λ©μμ§ κ°μλ₯Ό μμμΌ μ΄λ κ°λ₯
lazyListState.scrollToItem(messages.lastIndex)
- after
- μ.묻.λ° 0λ²μ§Έ μΈλ±μ€λ‘ μ€ν¬λ‘€μ λ΄λ¦¬λ©΄ κ·Έκ² μ΅μ λ©μμ§
lazyListState.scrollToItem(0)
μ€ν¬λ‘€ μ± μ λΆλ¦¬
μ§κΈκΉμ§ μ΅νλ¨μΌλ‘ μ€ν¬λ‘€νλ κ²½μ°μ λν΄ μΈκΈμ νμ§λ§, μ΅νλ¨ λΏλ§ μλλΌ νΉμ λ©μμ§λ‘ μ΄λνλ κ²½μ°λ μ‘΄μ¬ν©λλ€.
λνμ μΈ μμλ‘ βκ²μ κΈ°λ₯βμ΄ μμ΅λλ€. κ²μ κ²°κ³Όκ° μμΌλ©΄ λ©μμ§λ₯Ό νλ©΄μ νμνκ³ , νλ¨μ λ²νΌμΌλ‘ μ΄μ νΉμ λ€μ κ²μκ²°κ³Όλ‘ μ΄λν μ μμ΅λλ€. κΈ°λ₯ μ체λ μ¬νν΄ λ³΄μ΄μ§λ§ λ‘μ§μ νμ΄μ°λ©΄ μλΉν 볡μ‘ν νΈμ λλ€.
- κ²μ κ²°κ³Όμ ν΄λΉνλ λ©μμ§κ° λ©λͺ¨λ¦¬μ μλκ°?
- μμΌλ©΄ κ·Έ λ©μμ§λ‘ μ€ν¬λ‘€ μ΄λ
- λ©λͺ¨λ¦¬μ μλ€λ©΄ dbμ μ μ₯λ λ©μμ§ μ€ κ²μμ΄κ° ν¬ν¨λ λ©μμ§λ₯Ό μ°Ύλλ€.
- 2λ²μμ μ°Ύμ λ©μμ§ μλ€λ‘ λ©μμ§λ€μ κ°μ Έμ¨λ€.
- νλ©΄μ 3λ²μμ κ°μ Έμ¨ λ©μμ§λ€μ λΏλ¦¬κ³ , 2λ²μμ μ°Ύμ λ©μμ§λ‘ μ€ν¬λ‘€ μ΄λνλ€.
- λμ΄μ κ²μκ²°κ³Όκ° μμ λκΉμ§ μ΄μ /λ€μ λ²νΌμ λλ₯Όλλ§λ€ 1~4λ²μ κ³Όμ μ λ°λ³΅νλ€.
μ¬μ€ UI μμλ μ΄ λͺ¨λ κ³Όμ μ μκ³ μΆμ§ μμ΅λλ€. βμ΄λ€ λ©μμ§λ€μ νλ©΄μ λΏλ¦΄μ§β, βμ΄λ€ λ©μμ§λ‘ μ€ν¬λ‘€ μ΄λν μ§βλ§μ΄ κ΄μ¬μ¬μ λλ€. μ¬κΈ°μ μ κΉ! μ±ν 리λ΄μΌ 1νΈμΈ μμλμ ν¬μ€νΈμ μ λͺ©μμ μ μ μλ―, μ ν¬ νμ MVI ν¨ν΄μ μ μ©νμ¬ UI μ λ°μ΄νΈλ₯Ό κ΄λ¦¬νκ³ μμ΅λλ€. μμ§λ μ½μ§ μμλ€λ©΄?! μ§κΈ λΉμ₯ π [fromm μ±ν 리λ΄μΌ: MVI λμ λ° μ±λ₯ κ°μ ] λ°λ‘ κ°κΈ°
μ΄λ μ€ν¬λ‘€μ State
μ Effect
μ€ λ¬΄μμΌλ‘ κ΄λ¦¬ν΄μΌ ν κΉμ?
- μ΄κ°λ¨ μ€λͺ
State
: UIμ νμ¬ λͺ¨μ΅μ λνλ΄λ λ°μ΄ν°Effect
: μν λ³κ²½κ³Ό λ³λλ‘ μ²λ¦¬ν΄μΌ νλ μΌνμ± λμ
β
μ ν¬λ Effect
λ‘ κ΄λ¦¬νκΈ°λ‘ κ²°μ νμ΅λλ€. βμ΄λλ‘ μ€ν¬λ‘€μ μ΄λν΄λΌβλΌλ μ΄λ²€νΈκ° λ°μνλ©΄ LazyListState
μ μ€ν¬λ‘€ μ΄λ λ©μλλ₯Ό νΈμΆνλ μΌνμ± λμμΌλ‘ κ°μ£Όνλ κ²λλ€.
μμλ ν¬μ€νΈμ λμλλ₯Ό λΉλ € κ²μ κΈ°λ₯μ νννλ€λ©΄ μλμ κ°μ΄ λ©λλ€.
- μ± μμ΄ λͺ νν λΆλ¦¬λμμ΅λλ€. μ΄λ€ λ©μμ§λ‘ μ΄λν΄μΌ νλμ§μ νλ¨μ ViewModelμμ μ²λ¦¬νκ³ , μ€μ UIμμμ μ€ν¬λ‘€ λμμ Composableμμ λ¨μν βμ§μ μΈλ±μ€λ‘ μ€ν¬λ‘€βλ§ μνν©λλ€.
- λ¨λ°©ν₯ λ°μ΄ν° νλ¦μΌλ‘ UI λ³νλ₯Ό μμΈ‘νκΈ° μ©μ΄ν©λλ€.
λ°μ΄ν° μ΄κΈ°νμ scroll μ΄λ²€νΈ νμ΄λ°μ΄ μ΄κΈλ λ
κ²μ κ²°κ³Όλ₯Ό 보μ¬μ€ λ, λ©μμ§ λ°μ΄ν° μ΄κΈ°νμ λμμ μ€ν¬λ‘€μ μ΄λνκΈ° λλ¬Έμ μ’
μ’
LazyColumn
μ λ°μ΄ν°κ° μ
λ°μ΄νΈ λκΈ° μ μ μ€ν¬λ‘€ λμμ΄ μμλμ΄ μλ±ν λ©μμ§λ‘ μ€ν¬λ‘€μ΄ μ΄λλλ νμμ κ²ͺμμ΅λλ€.
μ΄λ΄λλ μ μλ €μ§ LazyListState
μ scrollToItem()
μ΄λ animateScrollToItem()
λ©μλ λμ requestScrollToItem() λ©μλλ₯Ό νμ©ν΄λ³΄μΈμ!
requestScrollToItem()
μ μ¦μ μ€ν¬λ‘€νμ§ μκ³ , λ€μ remeasure μμ μ 리μ€νΈλ₯Ό νΉμ νλͺ©μΌλ‘ μ€ν¬λ‘€νλλ‘ μμ²ν©λλ€. 리μ€νΈ λ°μ΄ν°κ° λ³κ²½λμλ€λ©΄, λ³κ²½λ λ°μ΄ν°λ₯Ό κΈ°μ€μΌλ‘ indexμ ν΄λΉνλ λ°μ΄ν°λ‘ μ€ν¬λ‘€ λ©λλ€.
μ¦, λ°μ΄ν° μ
λ°μ΄νΈ β μ€ν¬λ‘€ μ΄λ μμκ° λ³΄μ₯λμ΄ λ°μ΄ν°κ° μμ§ μ€λΉλμ§ μμλλ° μ€ν¬λ‘€μ΄ λ¨Όμ λ°μνμ¬ μ±ν¬κ° λ§μ§ μλ λ¬Έμ λ₯Ό λ°©μ§ν μ μμ΅λλ€.
λ§λ¬΄λ¦¬νλ©°
μ΄λ² ν¬μ€νΈλ‘ λ€λ£¬ λ΄μ© μΈμλ λ§μ Composeμμμ μνμ°©μ€μ κ³ λ―Όλ€μ΄ μμμ§λ§, λͺ¨λ λ€λ£° μλ μμ΄ UI νΉμ±μ κ³ λ €νμ¬ μ€κ³νκ³ κ΅¬νν λ΄μ©μΌλ‘ μ€λΉν΄ 보μμ΅λλ€. μ΄λ κ² ν° λ²μμ UIλ₯Ό μ€κ³νλ κ²μ μ²μμ΄μλλ°λ λΆκ΅¬νκ³ λ©μμ§ κΈ°λ₯μ κ³ λννκ³ μλ μ§κΈ, κ°λ° ν¨μ¨μ΄ ν¬κ² ν₯μλ¨μ μ€κ°νκ³ μμ΅λλ€. μμΌλ‘ μλ‘μ΄ κΈ°λ₯μ λμ± λΉ λ₯΄κ³ μμ μ μΌλ‘ μ λ³΄μΌ μ μλ κΈ°λ°μ΄ λ§λ ¨λμμΌλ, μ§μμ μΌλ‘ λ°μ νλ μ±ν κ²½νμ κΈ°λν΄μ£ΌμκΈ° λ°λλλ€!
νμ¬ fromm Androidνμ μΈμ¬ μμ μ€μ λλ€! μ ν¬μ ν¨κ» λ λμ μ½λλ₯Ό λ§λλ κ²μ κ΄μ¬μ΄ μμΌμλ€λ©΄?! π μ±μ© κ³΅κ³ λ³΄λ¬ κ°κΈ°