Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
유연한 Composable 설계
Search
HyunWoo Lee
July 20, 2024
Programming
0
700
유연한 Composable 설계
Google I/O Extended Korea Andorid 2024에서 진행한 유연한 Composable 설계 발표의 Speaker Deck입니다.
HyunWoo Lee
July 20, 2024
Tweet
Share
More Decks by HyunWoo Lee
See All by HyunWoo Lee
How Android Uses Data Structures Behind The Scenes
l2hyunwoo
0
480
Understanding Kotlin Multiplatform (Busan)
l2hyunwoo
0
44
Understanding Kotlin Multiplatform
l2hyunwoo
0
290
파급효과: From AI to Android Development
l2hyunwoo
0
230
선언형 UI에서의 상태관리
l2hyunwoo
0
540
선언형 UI를 학습할 때 알아둬야하는 키워드들
l2hyunwoo
0
450
Essential concepts to know when learning Declarative UI
l2hyunwoo
2
1.4k
React Native under the hood
l2hyunwoo
0
130
KotlinConf 2024 Global in South Korea Keynote
l2hyunwoo
0
130
Other Decks in Programming
See All in Programming
CJK and Unicode From a PHP Committer
youkidearitai
PRO
0
110
概念モデル→論理モデルで気をつけていること
sunnyone
3
290
FindyにおけるTakumi活用と脆弱性管理のこれから
rvirus0817
0
530
Swift Updates - Learn Languages 2025
koher
2
490
HTMLの品質ってなんだっけ? “HTMLクライテリア”の設計と実践
unachang113
4
2.9k
より安全で効率的な Go コードへ: Protocol Buffers Opaque API の導入
shwatanap
2
360
Testing Trophyは叫ばない
toms74209200
0
890
AIコーディングAgentとの向き合い方
eycjur
0
280
Amazon RDS 向けに提供されている MCP Server と仕組みを調べてみた/jawsug-okayama-2025-aurora-mcp
takahashiikki
1
110
Rancher と Terraform
fufuhu
2
550
アプリの "かわいい" を支えるアニメーションツールRiveについて
uetyo
0
270
CloudflareのChat Agent Starter Kitで簡単!AIチャットボット構築
syumai
2
500
Featured
See All Featured
Gamification - CAS2011
davidbonilla
81
5.4k
Save Time (by Creating Custom Rails Generators)
garrettdimon
PRO
32
1.6k
Docker and Python
trallard
46
3.6k
Producing Creativity
orderedlist
PRO
347
40k
The Invisible Side of Design
smashingmag
301
51k
JavaScript: Past, Present, and Future - NDC Porto 2020
reverentgeek
52
5.6k
Optimising Largest Contentful Paint
csswizardry
37
3.4k
Fantastic passwords and where to find them - at NoRuKo
philnash
52
3.4k
CoffeeScript is Beautiful & I Never Want to Write Plain JavaScript Again
sstephenson
162
15k
How to Think Like a Performance Engineer
csswizardry
26
1.9k
Evolution of real-time – Irina Nazarova, EuRuKo, 2024
irinanazarova
8
920
The Web Performance Landscape in 2024 [PerfNow 2024]
tammyeverts
9
810
Transcript
ਬোೠ Composable ࢸ҅ അ Viva Republica(Toss) Android/React Native Developer
Motivation
None
None
fun RepositoryCard() { Column { Row { Row { Image();
Text(); Chip(); } Image(); } Row { Text(); } Row { Props(); Props(); Props(); } } } private fun Props() { Row { Image(); Text(); } }
fun RepositoryCard() { Column { Title(title = “sept-android”, isPrivate =
false) Description() Row { Language(); Stars(); Forks(); } } } private fun Props() { Row { Image(); Text(); } }
ߣ ࣁ࣌ীࢲח Scalable Consistent Guide Others
Framework Library App
Framework Library App
Think and Plan
ܻח ઁ ࢜۽ Composableਸ ٜ݅ө?
ઁ, যڌѱ ࢜۽ Composableਸ ٜ݅ Ѿबਸ оઉঠೡө?
Single Responsibility Principle(SRP) ೞա ೣࣻ ೞա ଼
Single Responsibility Principle(SRP) ೞա ೣࣻ ೞա ଼
Ѣ ࠺तೠ ਊ۹۽ ডр ߸݅ ਃೠ ҃ Component ࢸ҅ ߑध
Think and Plan ౠ ਃҳࢎ೦ ইצ ҕాػ ࢎ೦ٜਸ ҳഅೞҊ ೞח Composable Ҋࣻળ(Higher level) API ࣻળ(Lower level) API
Ҋࣻળਵ۽ тࣻ۾ ز ח ݺഛ೧Ҋ ழझథ ৈח যઉঠ ೠ Component
ࢸ҅ ߑध Think and Plan
@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, )
@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 */ ) } }
ӝઓী ח ஹನք݅ਵ۽ ࠙ೞݶ ୶о۽ ٜ݅ ঋইب ػ. ߄௰ܳ ߊݺೞ
݃ۄ Think and Plan
Name and Parameters
Naming
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
// DO!! // InputField @Composable fun InputField(inputState: InputState) {
// ࢎਊ(Call-Site) val inputState = remember { InputState() } Button("Clear input", onClick = { inputState.clear() }) InputField(inputState)
// DON’T!! // InputField @Composable fun InputField(): UserInputState {
// पઁ ࢎਊ Button("Clear input", onClick = { …? }) val inputState = InputField()
1. Chip() 2. BasicTextField() 3. FilterChip() GoogleChip() FeatureXChip() 1. ߄۽
ࢎਊоמೠ ӝࠄ ஹನք 2. ୶оਵ۽ झఋੌ݂ ਃೠ ࣻ ળ ஹನք 3. ౠ Usecaseܳ оҊ ח ஹನ ք val LocalTheme = compositionLocalOf() val ThemeLocal = compositionLocalOf() Prefixing CompositionLocal Name and Parameters
Parameters
@Composable fun Chip( modifier: Modifier, onClick: () -> Unit, )
Chip( modifier = Modifier, onClick = { } ) { // TODO } ಁ۞ఠܳ ݺदਵ۽ ٘۞ղۄ → ಁ۞ఠо যڃ Ѫੋ ࡅܰѱ ঈ оמ Parameters Name and Parameters
// DON’T val LocalChipBorder = compositionLocalOf() @Composable fun Chip( modifier:
Modifier, onClick: () -> Unit, ) { val border = LocalChipBorder.current } ঐद ࢎਊ < ݺद ࢎਊ → CompositionLocal < State Hoisting Parameters Name and Parameters
// DO @Composable fun Chip( border: BorderStroke, ) { //
Set border } ঐद ࢎਊ < ݺद ࢎਊ → CompositionLocal < State Hoisting Parameters Name and Parameters
@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
@Composable fun Chip( modifier: Modifier ) @Composable fun Button( modifier:
Modifier = Modifier, ) @Composable fun Card( modifier: Modifier = Modifier, ) Compose ࢎਊٜ Ӓ ஹನք ࢎਊߑߨਸ যוب ఠٙ೮ӝী, যڌѱ ࢎਊೡ Ӓ ಁఢ ۚ ਵ۽ ೧ઉ. Modifiers Name and Parameters
@Composable fun Chip( modifier: Modifier ) UI ਃࣗܳ emitೞח Composable
Modifier ಁ۞ ఠ ࣻ۽ ઓ೧ঠೣ Modifiers Name and Parameters
@Composable fun Chip( label: @Composable () -> Unit, onClick: ()
-> Unit, modifier: Modifier = Modifier ) UI ਃࣗܳ emitೞח Composable Modifier ಁ۞ ఠ ࣻ۽ ઓ೧ঠೣ ݽٚ Optional Parameter о ߣ૩۽ ਤ೧ ঠೣ - First optional parameter Modifiers Name and Parameters
@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
@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
@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
@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
@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
@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
@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
@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
// 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
@Composable fun Chip( icon: @Composable () -> Unit? = null,
label: @Composable () -> Unit, ) Slots Single Slot Mutliple Slots content ಁ۞ఠ ݺद ಁ۞ఠ ഐױীࢲ ஹನքܳ ೧ࢲ ੑೞݶ ղࠗীࢲ ܳ ഝਊ೧ࢲ UIܳ ҳࢿೞח ߑध Name and Parameters
@Composable fun Chip( enalbled: Boolean = true, ) Chip( enabled
= true ) State State Hoistingਸ ӝ߈ਵ۽ غب۾ݶ ৻ࠗীࢲ ࢚కܳ ҙܻೡ ࣻ ب۾ ೞۄ Name and Parameters
@Composable fun Chip( enalbled: Boolean = true, onClick: () ->
Unit, ) // call-site Chip( enabled = true onClick = { } ) Events ࢚కח ৻ࠗীࢲ ઑೡ ࣻ ݅ ஹನքীࢲ ৻ࠗী नഐܳ ߉ਸ ࣻ ח ߑߨ ۈ ۄఠ۽ ѐߊо ߮ܳ ೡ ࣻ Name and Parameters
Conclusion
ೞա ஹನքח ೞա ଼ਸ APIܳ ਬোೞѱ ࢸ҅ೞ۰ݶ? Conclusion ୶࢚ചػ ࣻળ
APIܳ ӝ߈ਵ۽ Ҋࣻળ APIܳ ѐߊ оةࢿ જ Naming & Parameter ஶ߮࣌ Composableਸ ҳࢿೞח নೠ ਃࣗܳ Ҋ۰ • Slots • State • Event
Thank You HyunWoo Lee nunu.tv | toss Android (React Native)
Developer