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
Sponsored
·
Ship Features Fearlessly
Turn features on and off without deploys. Used by thousands of Ruby developers.
→
HyunWoo Lee
July 20, 2024
Programming
810
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
KotlinConf Extended South Korea 2026 Keynote
l2hyunwoo
0
150
Jindong: Introducing Declarative Haptics in Compose Multiplatform
l2hyunwoo
0
190
Navigating Dependency Injection with Metro
l2hyunwoo
1
510
How Android Uses Data Structures Behind The Scenes
l2hyunwoo
1
840
Understanding Kotlin Multiplatform (Busan)
l2hyunwoo
0
130
Understanding Kotlin Multiplatform
l2hyunwoo
0
410
파급효과: From AI to Android Development
l2hyunwoo
0
420
선언형 UI에서의 상태관리
l2hyunwoo
0
670
선언형 UI를 학습할 때 알아둬야하는 키워드들
l2hyunwoo
0
580
Other Decks in Programming
See All in Programming
AI主導のプログラミング学習アプリを作ってみた
econanringo
0
160
KiroのSpecで「五目並べ」を作ってみる
satoshi256kbyte
1
370
Are APIs Still Relevant in the AI Era?
soyuka
0
460
AIに “答え“を書かせるのを やめてみた
___akari11
0
120
iOS 27でニュースアプリはどう変わる!? 〜日経電子版の新機能対応と、開発事例から〜
lynnswap
7
13k
RAG の “R” を Swift で覗いてみる 〜「意味から探す」検索の仕組み〜
nao_randd
0
160
見えないものを探る要求要件定義に必要な基本的思考 / invisible-requirement-thinking
minodriven
15
8.3k
コードで差別化できない時代の ソフトウェアエンジニアリング / Software Engineering in an Era Where Code Doesn’t Differentiate
kishida
2
160
Embedded Swiftで作る自作USBデバイス によるiOSデバイスの自動テスト / iOSDC Japan 2026 glassfiber
glassfiber
0
340
ソニーのクラウド共通基盤の変遷とAI時代の開発スタイルに合わせた進化 / The Journey of Sony’s Common Cloud Platform and Its Evolution for AI-Native Development
kenjiyoneyama
0
250
contenteditable と日本語入力に向き合う
colorful12
0
190
HTML-in-Canvasで作る未来のWeb UI表現
clockmaker
4
4.8k
Featured
See All Featured
Marketing Yourself as an Engineer | Alaka | Gurzu
gurzu
0
330
How to Talk to Developers About Accessibility
jct
2
570
Building the Perfect Custom Keyboard
takai
2
900
The AI Search Optimization Roadmap by Aleyda Solis
aleyda
2
6.3k
Creating an realtime collaboration tool: Agile Flush - .NET Oxford
marcduiker
35
2.6k
Thoughts on Productivity
jonyablonski
76
5.4k
Stewardship and Sustainability of Urban and Community Forests
pwiseman
0
550
ラッコキーワード サービス紹介資料
rakko
1
5.3M
Ten Tips & Tricks for a 🌱 transition
stuffmc
1
260
The World Runs on Bad Software
bkeepers
PRO
72
12k
The Limits of Empathy - UXLibs8
cassininazir
2
720
How STYLIGHT went responsive
nonsquared
100
6.3k
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