$30 off During Our Annual Pro Sale. View Details »

유연한 Composable 설계

유연한 Composable 설계

Google I/O Extended Korea Andorid 2024에서 진행한 유연한 Composable 설계 발표의 Speaker Deck입니다.

HyunWoo Lee

July 20, 2024
Tweet

More Decks by HyunWoo Lee

Other Decks in Programming

Transcript

  1. fun RepositoryCard() { Column { Row { Row { Image();

    Text(); Chip(); } Image(); } Row { Text(); } Row { Props(); Props(); Props(); } } } private fun Props() { Row { Image(); Text(); } }
  2. fun RepositoryCard() { Column { Title(title = “sept-android”, isPrivate =

    false) Description() Row { Language(); Stars(); Forks(); } } } private fun Props() { Row { Image(); Text(); } }
  3. Ѣ੄ ࠺तೠ ਊ۹۽ ডр੄ ߸઱݅ ೙ਃೠ ҃਋ Component੄ ࢸ҅ ߑध

    Think and Plan ౠ੿ ਃҳࢎ೦੉ ইצ ҕాػ ࢎ೦ٜਸ ҳഅೞҊ੗ ೞח Composable Ҋࣻળ(Higher level) API ੷ࣻળ(Lower level) API
  4. @Composable fun AssistChip( onClick: () -> Unit, label: @Composable ()

    -> Unit, modifier: Modifier = Modifier, enabled: Boolean = true, leadingIcon: @Composable (() -> Unit)? = null, trailingIcon: @Composable (() -> Unit)? = null, /* etc */ ) = Chip( modifier = modifier, onClick = onClick, enabled = enabled, label = label, leadingIcon = leadingIcon, trailingIcon = trailingIcon, )
  5. @Composable fun Chip( onClick: () -> Unit, label: @Composable ()

    -> Unit, modifier: Modifier = Modifier, enabled: Boolean = true, leadingIcon: @Composable (() -> Unit)? = null, trailingIcon: @Composable (() -> Unit)? = null, /* etc */ ) { Surface( onClick = onClick, modifier = modifier.semantics { role = Role.Button }, enabled = enabled /* etc */ ) { ChipContent( label = label, leadingIcon = leadingIcon, trailingIcon = trailingIcon, /* etc */ ) } }
  6. fun FilterChip() fun filterChip() • Composeীࢲ UI ҳࢿਃࣗܳ աఋ ն

    • ௿ېझ ಴ӝ ഋधਸ ରਊ fun gdgState(): State fun GdgState(): State • ೣࣻ ֎੉߁ ӏ஗ਸ ࢎਊ • ೣࣻח чਸ ߈ജೞѢա UI ҙ۲ ਃࣗ ٜਸ emit ೧ঠೠ׮. fun rememberCoroutineScope(): CoroutineScope fun createCoroutineScope(): CoroutineScope • Recompositionীࢲب чਸ ਬ૑ೞ ח Ѫਸ ಴द UI ҳࢿਃࣗܳ emitೞח @Composable Name and Parameters чਸ ܻఢೞח @Composable rememberܳ ࢎਊೞח @Composable
  7. // DO!! // InputField ੿੄ @Composable fun InputField(inputState: InputState) {

    // ࢎਊ୊(Call-Site) val inputState = remember { InputState() } Button("Clear input", onClick = { inputState.clear() }) InputField(inputState)
  8. // DON’T!! // InputField ੿੄ @Composable fun InputField(): UserInputState {

    // पઁ ࢎਊ୊ Button("Clear input", onClick = { ਺…? }) val inputState = InputField()
  9. 1. Chip() 2. BasicTextField() 3. FilterChip() GoogleChip() FeatureXChip() 1. ߄۽

    ࢎਊоמೠ ӝࠄ ஹನք౟ 2. ୶о੸ਵ۽ झఋੌ݂੉ ೙ਃೠ ੷ࣻ ળ ஹನք౟ 3. ౠ੿ Usecaseܳ о૑Ҋ ੓ח ஹನ ք౟ val LocalTheme = compositionLocalOf() val ThemeLocal = compositionLocalOf() Prefixing CompositionLocal Name and Parameters
  10. @Composable fun Chip( modifier: Modifier, onClick: () -> Unit, )

    Chip( modifier = Modifier, onClick = { } ) { // TODO } ಁ۞޷ఠܳ ݺद੸ਵ۽ ٘۞ղۄ → ੉ ಁ۞޷ఠо যڃ Ѫੋ૑ ࡅܰѱ ౵ঈ оמ Parameters Name and Parameters
  11. // DON’T val LocalChipBorder = compositionLocalOf() @Composable fun Chip( modifier:

    Modifier, onClick: () -> Unit, ) { val border = LocalChipBorder.current } ঐद੸ ࢎਊ < ݺद੸ ࢎਊ → CompositionLocal < State Hoisting Parameters Name and Parameters
  12. // DO @Composable fun Chip( border: BorderStroke, ) { //

    Set border } ঐद੸ ࢎਊ < ݺद੸ ࢎਊ → CompositionLocal < State Hoisting Parameters Name and Parameters
  13. @Composable fun Chip( modifier: Modifier ) // Call-Site Chip(Modifier.padding(8.dp)) Components

    → define own internal behavior and appearance Modifiers -> modify external Modifiers Name and Parameters
  14. @Composable fun Chip( modifier: Modifier ) @Composable fun Button( modifier:

    Modifier = Modifier, ) @Composable fun Card( modifier: Modifier = Modifier, ) Compose ࢎਊ੗ٜ਷ ੉޷ Ӓ ஹನք౟ ࢎਊߑߨਸ যו੿ب ఠٙ೮ӝী, যڌѱ ࢎਊೡ૑ Ӓ ಁఢ੉ ؀ۚ ੸ਵ۽ ੿೧ઉ੓׮. Modifiers Name and Parameters
  15. @Composable fun Chip( modifier: Modifier ) UI ਃࣗܳ emitೞח Composable਷

    Modifier ಁ۞ ޷ఠ ೙ࣻ۽ ઓ੤೧ঠೣ Modifiers Name and Parameters
  16. @Composable fun Chip( label: @Composable () -> Unit, onClick: ()

    -> Unit, modifier: Modifier = Modifier ) UI ਃࣗܳ emitೞח Composable਷ Modifier ಁ۞ ޷ఠ ೙ࣻ۽ ઓ੤೧ঠೣ ݽٚ Optional Parameter ઺ о੢ ୐ߣ૩۽ ਤ஖೧ ঠೣ - First optional parameter Modifiers Name and Parameters
  17. @Composable fun Chip( modifier: Modifier = Modifier ) { Row(modifier

    = modifier.size(16.dp) } // Call-site Chip( modifier = Modifier.padding(8.dp) ) UI ਃࣗܳ emitೞח Composable਷ Modifier ಁ۞ ޷ఠ ೙ࣻ۽ ઓ੤೧ঠೣ ݽٚ Optional Parameter ઺ о੢ ୐ߣ૩۽ ਤ஖೧ ঠೣ - First optional parameter Monoid Type → ಁ۞޷ఠীࢲ ֈӟ чਸ Ӓ؀۽ ղ ࠗীࢲ Ӓ؀۽ ࢎਊоמ + ২࣌ ୶о оמ Modifiers Name and Parameters
  18. @Composable fun Chip( modifier: Modifier = Modifier ) { Row(modifier

    = modifier.size(16.dp) } UI ਃࣗܳ emitೞח Composable਷ Modifier ಁ۞ ޷ఠ ೙ࣻ۽ ઓ੤೧ঠೣ ݽٚ Optional Parameter ઺ о੢ ୐ߣ૩۽ ਤ஖೧ ঠೣ - First optional parameter Monoid Type → ಁ۞޷ఠীࢲ ֈӟ чਸ Ӓ؀۽ ղ ࠗীࢲ Ӓ؀۽ ࢎਊоמ + ২࣌ ୶о оמ ೣࣻ੄ ಁ۞޷ఠ ઺ Modifier ఋੑ਷ ױ ೞաৈঠೣ Modifiers Name and Parameters
  19. @Composable fun Chip( enabled: Boolean, icon: @Composable () -> Unit,

    modifier: Modifier = Modifier, shape: Shape = ChipDefaults…, colors: ChipColors = ChipDefaults… ) { Surface( modifier = modifier, enabled = enabled, shape = shape, color = colors.containerColor(enabled) ) { // etc… } } Chip(modifier = Modifier.padding(8.dp)) Modifiers or explicit parameters? ஹನ੷࠶੄ ೯زҗ UIܳ ੿੄ೞח чੋؘ Modifierী ֍ਸ ࣻ হח ఋੑ → Explicit Parameters Modifier۽ ֍ਸ ࣻ ੓ח ఋੑ → Modifier Name and Parameters
  20. @Composable fun Chip( onClick: () -> Unit, enabled: Boolean, icon:

    @Composable () -> Unit, modifier: Modifier = Modifier, shape: Shape = ChipDefaults…, colors: ChipColors = ChipDefaults…, content: @Composable () -> Unit, ) Ordering 1. Required Params 2. Modifier 3. Optional Params 4. @Composable content params Name and Parameters
  21. @Composable fun Chip( onClick: () -> Unit, enabled: Boolean, icon:

    @Composable () -> Unit, modifier: Modifier = Modifier, shape: Shape = ChipDefaults…, colors: ChipColors = ChipDefaults…, content: @Composable () -> Unit, ) Ordering 1. Required Params 2. Modifier 3. Optional Params 4. @Composable content params Name and Parameters
  22. @Composable fun Chip( onClick: () -> Unit, modifier: Modifier =

    Modifier, enabled: Boolean = true, shape: Shape = ChipDefaults.shape, colors: ChipColors = ChipDefaults…, icon: @Composable () -> Unit? = null, content: @Composable () -> Unit, ) Default and nullable Empty Nullable Default Ҷ੉ হযب غח ӝמ ੑ۱੉ ೙ਃೣ, ೞ૑݅ ࠼ ч੉ ٜযоب ؽ ࠺য੓ਵݶ উغח ч Name and Parameters
  23. @Composable fun Chip( onClick: () -> Unit, modifier: Modifier =

    Modifier, enabled: Boolean = true, elevation: Dp = 8.dp shape: Shape = ChipDefaults.shape, colors: ChipColors = ChipDefaults…, icon: @Composable () -> Unit? = null, content: @Composable () -> Unit, ) Styling Defaults Inline ૣҊ ৘ஏоמೠ ҃਋ ӝࠄч੉ ݆੉ ೙ਃೠ ҃਋ ࢚కчী ٮۄ ࠙ӝо ୊ܻغযঠ ೞח ҃਋ Name and Parameters
  24. @Composable fun Chip( onClick: () -> Unit, shape: Shape =

    ChipDefaults.shape, colors: ChipColors = ChipDefaults…, ) object ChipDefaults { val shape = InputChip.ContainerShape fun colors(): ChipColors fun elevation(): ChipElevation } Styling Defaults Inline ૣҊ ৘ஏоמೠ ҃਋ ӝࠄч੉ ݆੉ ೙ਃೠ ҃਋ ࢚కчী ٮۄ ࠙ӝо ୊ܻغযঠ ೞח ҃਋ Name and Parameters
  25. // Kotlin 2.2 Experimental dataarg class ChipColors( container: Color, label:

    Color ) @Composable fun Chip( onClick: () -> Unit, modifier: Modifier = Modifier, enabled: Boolean = true, dataarg colors: ChipColors, ) Chip( onClick = {}, container = Color(…) ) // Kotlin Language Features in 2.0 and beyond https://www.youtube.com/watch?v=tAGJ5zJXJ7w // ೠҴয ߡ੹ (KotlinConf’24 Global South Korea) https://speakerdeck.com/dalinaum/recap-kotlin- language-features-in-2-dot-0-and-beyond- michail-zarecenskij Styling Defaults Inline ૣҊ ৘ஏоמೠ ҃਋ ӝࠄч੉ ݆੉ ೙ਃೠ ҃਋ ࢚కчী ٮۄ ࠙ӝо ୊ܻغযঠ ೞח ҃਋ Name and Parameters
  26. @Composable fun Chip( icon: @Composable () -> Unit? = null,

    label: @Composable () -> Unit, ) Slots Single Slot Mutliple Slots content ಁ۞޷ఠ ݺद੸ ಁ۞޷ఠ ഐ୹ױীࢲ ૒੽ ஹನք౟ܳ ੿੄೧ࢲ ઱ੑೞݶ ղࠗীࢲ ੉ܳ ഝਊ೧ࢲ UIܳ ҳࢿೞח ߑध Name and Parameters
  27. @Composable fun Chip( enalbled: Boolean = true, ) Chip( enabled

    = true ) State State Hoistingਸ ӝ߈ਵ۽ غب۾੉ݶ ৻ࠗীࢲ ࢚కܳ ҙܻೡ ࣻ ੓ب۾ ೞۄ Name and Parameters
  28. @Composable fun Chip( enalbled: Boolean = true, onClick: () ->

    Unit, ) // call-site Chip( enabled = true onClick = { } ) Events ࢚కח ৻ࠗীࢲ ઑ੺ೡ ࣻ ੓૑݅ ஹನք౟ীࢲ ৻ࠗী ઴ नഐܳ ߉ਸ ࣻ ੓ח ߑߨ ۈ׮ ౵ۄ޷ఠ۽ ѐߊ੗о ੉߮౟ܳ ૑੿ೡ ࣻ ੓਺ Name and Parameters
  29. ೞա੄ ஹನք౟ח ೞա੄ ଼੐ਸ APIܳ ਬোೞѱ ࢸ҅ೞ۰ݶ? Conclusion ୶࢚ചػ ੷ࣻળ

    APIܳ ӝ߈ਵ۽ Ҋࣻળ APIܳ ѐߊ оةࢿ੉ જ਷ Naming & Parameter ஶ߮࣌ Composableਸ ҳࢿೞח ׮নೠ ਃࣗܳ Ҋ۰ • Slots • State • Event