Lock in $30 Savings on PRO—Offer Ends Soon! ⏳
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
유연한 Composable 설계
Search
HyunWoo Lee
July 20, 2024
Programming
0
730
유연한 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
Navigating Dependency Injection with Metro
l2hyunwoo
1
180
How Android Uses Data Structures Behind The Scenes
l2hyunwoo
1
660
Understanding Kotlin Multiplatform (Busan)
l2hyunwoo
0
64
Understanding Kotlin Multiplatform
l2hyunwoo
0
310
파급효과: From AI to Android Development
l2hyunwoo
0
290
선언형 UI에서의 상태관리
l2hyunwoo
0
600
선언형 UI를 학습할 때 알아둬야하는 키워드들
l2hyunwoo
0
500
Essential concepts to know when learning Declarative UI
l2hyunwoo
2
1.5k
React Native under the hood
l2hyunwoo
0
150
Other Decks in Programming
See All in Programming
AIコーディングエージェント(Gemini)
kondai24
0
280
PC-6001でPSG曲を鳴らすまでを全部NetBSD上の Makefile に押し込んでみた / osc2025hiroshima
tsutsui
0
180
LLMで複雑な検索条件アセットから脱却する!! 生成的検索インタフェースの設計論
po3rin
4
970
「コードは上から下へ読むのが一番」と思った時に、思い出してほしい話
panda728
PRO
39
26k
Pythonではじめるオープンデータ分析〜書籍の紹介と書籍で紹介しきれなかった事例の紹介〜
welliving
3
600
0→1 フロントエンド開発 Tips🚀 #レバテックMeetup
bengo4com
0
390
チームをチームにするEM
hitode909
0
380
クラウドに依存しないS3を使った開発術
simesaba80
0
170
メルカリのリーダビリティチームが取り組む、AI時代のスケーラブルな品質文化
cloverrose
2
380
Basic Architectures
denyspoltorak
0
120
組み合わせ爆発にのまれない - 責務分割 x テスト
halhorn
1
160
まだ間に合う!Claude Code元年をふりかえる
nogu66
5
900
Featured
See All Featured
Google's AI Overviews - The New Search
badams
0
870
Building Applications with DynamoDB
mza
96
6.8k
Reflections from 52 weeks, 52 projects
jeffersonlam
355
21k
The Pragmatic Product Professional
lauravandoore
37
7.1k
Navigating Weather and Climate Data
rabernat
0
53
Have SEOs Ruined the Internet? - User Awareness of SEO in 2025
akashhashmi
0
190
Paper Plane
katiecoart
PRO
0
44k
Building an army of robots
kneath
306
46k
Leo the Paperboy
mayatellez
0
1.3k
Music & Morning Musume
bryan
46
7k
How GitHub (no longer) Works
holman
316
140k
VelocityConf: Rendering Performance Case Studies
addyosmani
333
24k
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