Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
유연한 Composable 설계
Search
HyunWoo Lee
July 20, 2024
Programming
820
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
유연한 Composable 설계
Google I/O Extended Korea Andorid 2024에서 진행한 유연한 Composable 설계 발표의 Speaker Deck입니다.
HyunWoo Lee
July 20, 2024
More Decks by HyunWoo Lee
See All by HyunWoo Lee
선언형 햅틱 라이브러리 진동을 소개합니다
l2hyunwoo
1
300
우리의 Nitro Modules는 당신의 Turbo Modules보다 아름답다
l2hyunwoo
0
260
KotlinConf Extended South Korea 2026 Keynote
l2hyunwoo
0
160
Jindong: Introducing Declarative Haptics in Compose Multiplatform
l2hyunwoo
0
210
Navigating Dependency Injection with Metro
l2hyunwoo
1
530
How Android Uses Data Structures Behind The Scenes
l2hyunwoo
1
850
Understanding Kotlin Multiplatform (Busan)
l2hyunwoo
0
130
Understanding Kotlin Multiplatform
l2hyunwoo
0
430
파급효과: From AI to Android Development
l2hyunwoo
0
430
Other Decks in Programming
See All in Programming
3回つくってわかった、 定期実行ジョブ基盤の本質情報
takai
4
3.8k
プロジェクトコードをキレイキレイしよう!暗黙的な参照を読み解く静的解析
ostk0069
0
210
作れるエンジニアから、価値を届けるエンジニアへ
ryunakayama
1
240
クラウドエージェントは、 何がそんなに便利なのか / what makes cloud agents so useful
rkaga
5
810
[JA] Domain Modeling with Vanilla Rails: 「操作」から再考するRailsの設計論
yasaichi
4
1.8k
全ての永続トークンを、生まれる前に消し去りたい!
sylph01
3
1.7k
AI時代のTerminal環境を UNIX哲学で設計・運用する
yasunori0418
1
350
Seven New Principles of Software Engineering
yegor256
0
470
Engineering Biometric UX Across Android Versions | DroidKnights 2026
ryunen344
1
190
Getting Started with Vibe Coding
miccheng
0
190
Kotlinize Is Not Just Converting to Kotlin
chigichan24
1
220
ChromeでローカルLLM
ryu1013
0
200
Featured
See All Featured
Building Adaptive Systems
keathley
44
3.3k
How STYLIGHT went responsive
nonsquared
100
6.4k
Lessons Learnt from Crawling 1000+ Websites
charlesmeaden
PRO
1
1.7k
Learning to Love Humans: Emotional Interface Design
aarron
275
41k
Amusing Abliteration
ianozsvald
1
380
Cheating the UX When There Is Nothing More to Optimize - PixelPioneers
stephaniewalter
287
14k
Creating an realtime collaboration tool: Agile Flush - .NET Oxford
marcduiker
35
2.6k
Templates, Plugins, & Blocks: Oh My! Creating the theme that thinks of everything
marktimemedia
31
2.9k
Have SEOs Ruined the Internet? - User Awareness of SEO in 2025
akashhashmi
0
550
Introduction to Domain-Driven Design and Collaborative software design
baasie
1
1.1k
The AI Search Optimization Roadmap by Aleyda Solis
aleyda
2
6.4k
Leveraging Curiosity to Care for An Aging Population
cassininazir
1
560
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