Slide 1

Slide 1 text

2024 Compose Gardener Compose Runtime으로 나만의 UI 만들기

Slide 2

Slide 2 text

No content

Slide 3

Slide 3 text

Ji Sungbin [email protected] github.com/jisungbin sungb.in __ . (*). /\-| -;-| (*) |___

Slide 4

Slide 4 text

컴포즈 런타임의 동작 방식을 이해하고 UI와 어떻게 연결되는지 알아봅니다 Introducing the 
 Jetpack Compose Runtime __ . (*). /\-| -;-| (*) |___

Slide 5

Slide 5 text

T opics Applier UI 노드 순회 담당 Recomposer UI 노드 새로고침 담당 Composition UI 노드 관리 담당 __ . (*). /\-| -;-| (*) |___

Slide 6

Slide 6 text

T opics Applier UI 노드 순회 담당 Recomposer UI 노드 새로고침 담당 Composition UI 노드 관리 담당 __ . (*). /\-| -;-| (*) |___

Slide 7

Slide 7 text

__ . (*). /\-| -;-| (*) |___

Slide 8

Slide 8 text

Material (Card) @Composable @Composable (content: () -> Unit) {
 ( Modifier. (...)) {
 content()
 }
 } fun Card surface Box modifier = __ . (*). /\-| -;-| (*) |___

Slide 9

Slide 9 text

Material (Card) F oundation (Box) @Composable @Composable (content: BoxScope.() -> Unit) { ( { BoxScopeInstance.content() } ) } fun Box Layout content = __ . (*). /\-| -;-| (*) |___

Slide 10

Slide 10 text

Material (Card) F oundation (Box) Ui (Layout) @Composable @Composable (content: () -> Unit) {
 (
 ComposeUiNode. ,
 content
 )
 } fun Layout ComposeNode factory = content = Constructor __ . (*). /\-| -;-| (*) |___

Slide 11

Slide 11 text

Material (Card) F oundation (Box) Ui (Layout) Runtime (ComposeNode) @Composable @Composable < (
 factory: () -> ,
 content: () -> Unit
 ) {
 .startNode()
 .createNode(factory)
 content()
 .endNode()
 } fun T> ComposeNode T currentComposer currentComposer currentComposer __ . (*). /\-| -;-| (*) |___

Slide 12

Slide 12 text

Column __ . (*). /\-| -;-| (*) |___

Slide 13

Slide 13 text

Header Image Column __ . (*). /\-| -;-| (*) |___

Slide 14

Slide 14 text

Header Image Row Column __ . (*). /\-| -;-| (*) |___

Slide 15

Slide 15 text

Header Image Title Icon Row Column __ . (*). /\-| -;-| (*) |___

Slide 16

Slide 16 text

Description Header Image Title Row Icon Column __ . (*). /\-| -;-| (*) |___

Slide 17

Slide 17 text

Description Row Header Image Title Row Icon Column __ . (*). /\-| -;-| (*) |___

Slide 18

Slide 18 text

Description Header Image Title Row Icon Topic Topic Row Column __ . (*). /\-| -;-| (*) |___

Slide 19

Slide 19 text

Description Header Image Title Row Icon Topic Topic Row Column Column HeaderImage Row Title Icon Description Row Topic Topic {
 ()
 {
 ()
 ()
 }
 ()
 {
 ()
 ()
 }
 } __ . (*). /\-| -;-| (*) |___

Slide 20

Slide 20 text

Applier 사용된 컴포저블을 트리 구조로 배치하고 순회하는 방법을 정의합니다. current: 현재 컴포저블 down(): 현재 컴포저블의 다음 자식 컴포저블로 이동 insert(): 현재 컴포저블에 자식 컴포저블 추가 up(): 현재 컴포저블의 부모 컴포저블로 이동 __ . (*). /\-| -;-| (*) |___

Slide 21

Slide 21 text

Column current Column {
 HeaderImage()
 Row {
 Title()
 Icon()
 }
 Description()
 Row {
 Topic()
 Topic()
 }
 } __ . (*). /\-| -;-| (*) |___

Slide 22

Slide 22 text

Header Image insert() Column Column HeaderImage {
 ()
 Row {
 Title()
 Icon()
 }
 Description()
 Row {
 Topic()
 Topic()
 }
 } __ . (*). /\-| -;-| (*) |___

Slide 23

Slide 23 text

Header Image down() Column Column HeaderImage {
 ()
 Row {
 Title()
 Icon()
 }
 Description()
 Row {
 Topic()
 Topic()
 }
 } __ . (*). /\-| -;-| (*) |___

Slide 24

Slide 24 text

Header Image Column Column HeaderImage {
 ()
 Row {
 Title()
 Icon()
 }
 Description()
 Row {
 Topic()
 Topic()
 }
 } __ . (*). /\-| -;-| (*) |___

Slide 25

Slide 25 text

up() Header Image Column Column HeaderImage {
 ()
 Row {
 Title()
 Icon()
 }
 Description()
 Row {
 Topic()
 Topic()
 }
 } __ . (*). /\-| -;-| (*) |___

Slide 26

Slide 26 text

Header Image Column Column HeaderImage {
 ()
 Row {
 Title()
 Icon()
 }
 Description()
 Row {
 Topic()
 Topic()
 }
 } __ . (*). /\-| -;-| (*) |___

Slide 27

Slide 27 text

Header Image Row insert() Column Column HeaderImage Row {
 ()
 {
 Title()
 Icon()
 }
 Description()
 Row {
 Topic()
 Topic()
 }
 } __ . (*). /\-| -;-| (*) |___

Slide 28

Slide 28 text

Header Image Row Column Column HeaderImage Row {
 ()
 {
 Title()
 Icon()
 }
 Description()
 Row {
 Topic()
 Topic()
 }
 } down() __ . (*). /\-| -;-| (*) |___

Slide 29

Slide 29 text

Header Image Row Column Column HeaderImage Row {
 ()
 {
 Title()
 Icon()
 }
 Description()
 Row {
 Topic()
 Topic()
 }
 } __ . (*). /\-| -;-| (*) |___

Slide 30

Slide 30 text

Header Image insert() Title Row Column Column HeaderImage Row Title {
 ()
 {
 ()
 Icon()
 }
 Description()
 Row {
 Topic()
 Topic()
 }
 } __ . (*). /\-| -;-| (*) |___

Slide 31

Slide 31 text

Header Image down() Title Row Column Column HeaderImage Row Title {
 ()
 {
 ()
 Icon()
 }
 Description()
 Row {
 Topic()
 Topic()
 }
 } __ . (*). /\-| -;-| (*) |___

Slide 32

Slide 32 text

Header Image Title Row Column Column HeaderImage Row Title {
 ()
 {
 ()
 Icon()
 }
 Description()
 Row {
 Topic()
 Topic()
 }
 } __ . (*). /\-| -;-| (*) |___

Slide 33

Slide 33 text

Header Image Title Row Column Column HeaderImage Row Title {
 ()
 {
 ()
 Icon()
 }
 Description()
 Row {
 Topic()
 Topic()
 }
 } up() __ . (*). /\-| -;-| (*) |___

Slide 34

Slide 34 text

Header Image Title Row Column Column HeaderImage Row Title {
 ()
 {
 ()
 Icon()
 }
 Description()
 Row {
 Topic()
 Topic()
 }
 } __ . (*). /\-| -;-| (*) |___

Slide 35

Slide 35 text

Header Image insert() Title Column Icon Row Column HeaderImage Row Title Icon {
 ()
 {
 ()
 ()
 }
 Description()
 Row {
 Topic()
 Topic()
 }
 } __ . (*). /\-| -;-| (*) |___

Slide 36

Slide 36 text

Header Image down() Title Column Icon Row Column HeaderImage Row Title Icon {
 ()
 {
 ()
 ()
 }
 Description()
 Row {
 Topic()
 Topic()
 }
 } __ . (*). /\-| -;-| (*) |___

Slide 37

Slide 37 text

Header Image Title Column Icon Row Column HeaderImage Row Title Icon {
 ()
 {
 ()
 ()
 }
 Description()
 Row {
 Topic()
 Topic()
 }
 } __ . (*). /\-| -;-| (*) |___

Slide 38

Slide 38 text

Header Image Title Column Icon Row Column HeaderImage Row Title Icon {
 ()
 {
 ()
 ()
 }
 Description()
 Row {
 Topic()
 Topic()
 }
 } up() __ . (*). /\-| -;-| (*) |___

Slide 39

Slide 39 text

Header Image Title Column Icon Row Column HeaderImage Row Title Icon {
 ()
 {
 ()
 ()
 }
 Description()
 Row {
 Topic()
 Topic()
 }
 } __ . (*). /\-| -;-| (*) |___

Slide 40

Slide 40 text

Header Image Title Column Icon Row Column HeaderImage Row Title Icon {
 ()
 {
 ()
 ()
 }
 Description()
 Row {
 Topic()
 Topic()
 }
 } up() __ . (*). /\-| -;-| (*) |___

Slide 41

Slide 41 text

Header Image Title Column Icon Row Column HeaderImage Row Title Icon {
 ()
 {
 ()
 ()
 }
 Description()
 Row {
 Topic()
 Topic()
 }
 } __ . (*). /\-| -;-| (*) |___

Slide 42

Slide 42 text

Header Image Title Icon Row Description Column insert() Column HeaderImage Row Title Icon Description {
 ()
 {
 ()
 ()
 }
 ()
 Row {
 Topic()
 Topic()
 }
 } __ . (*). /\-| -;-| (*) |___

Slide 43

Slide 43 text

Header Image Title Icon Row Description Column down() Column HeaderImage Row Title Icon Description {
 ()
 {
 ()
 ()
 }
 ()
 Row {
 Topic()
 Topic()
 }
 } __ . (*). /\-| -;-| (*) |___

Slide 44

Slide 44 text

Header Image Title Icon Row Description Column Column HeaderImage Row Title Icon Description {
 ()
 {
 ()
 ()
 }
 ()
 Row {
 Topic()
 Topic()
 }
 } __ . (*). /\-| -;-| (*) |___

Slide 45

Slide 45 text

Header Image Title Icon Row Description Column Column HeaderImage Row Title Icon Description {
 ()
 {
 ()
 ()
 }
 ()
 Row {
 Topic()
 Topic()
 }
 } up() __ . (*). /\-| -;-| (*) |___

Slide 46

Slide 46 text

Header Image Title Icon Row Description Column Column HeaderImage Row Title Icon Description {
 ()
 {
 ()
 ()
 }
 ()
 Row {
 Topic()
 Topic()
 }
 } __ . (*). /\-| -;-| (*) |___

Slide 47

Slide 47 text

Header Image Title Icon Row Description Row Column Column HeaderImage Row Title Icon Description Row {
 ()
 {
 ()
 ()
 }
 ()
 {
 Topic()
 Topic()
 }
 } insert() __ . (*). /\-| -;-| (*) |___

Slide 48

Slide 48 text

Header Image Title Icon Row Description Row Column Column HeaderImage Row Title Icon Description Row {
 ()
 {
 ()
 ()
 }
 ()
 {
 Topic()
 Topic()
 }
 } down() __ . (*). /\-| -;-| (*) |___

Slide 49

Slide 49 text

Header Image Title Icon Row Description Row Column Column HeaderImage Row Title Icon Description Row {
 ()
 {
 ()
 ()
 }
 ()
 {
 Topic()
 Topic()
 }
 } __ . (*). /\-| -;-| (*) |___

Slide 50

Slide 50 text

Header Image Title Icon Row Description Column Topic Row insert() Column HeaderImage Row Title Icon Description Row Topic {
 ()
 {
 ()
 ()
 }
 ()
 {
 ()
 Topic()
 }
 } __ . (*). /\-| -;-| (*) |___

Slide 51

Slide 51 text

Header Image Title Icon Row Description Column Topic Row down() Column HeaderImage Row Title Icon Description Row Topic {
 ()
 {
 ()
 ()
 }
 ()
 {
 ()
 Topic()
 }
 } __ . (*). /\-| -;-| (*) |___

Slide 52

Slide 52 text

Header Image Title Icon Row Description Column Topic Row Column HeaderImage Row Title Icon Description Row Topic {
 ()
 {
 ()
 ()
 }
 ()
 {
 ()
 Topic()
 }
 } __ . (*). /\-| -;-| (*) |___

Slide 53

Slide 53 text

Header Image Title Icon Row Description Column Topic Row Column HeaderImage Row Title Icon Description Row Topic {
 ()
 {
 ()
 ()
 }
 ()
 {
 ()
 Topic()
 }
 } up() __ . (*). /\-| -;-| (*) |___

Slide 54

Slide 54 text

Header Image Title Icon Row Description Column Topic Row Column HeaderImage Row Title Icon Description Row Topic {
 ()
 {
 ()
 ()
 }
 ()
 {
 ()
 Topic()
 }
 } __ . (*). /\-| -;-| (*) |___

Slide 55

Slide 55 text

Header Image Title Icon Row Description insert() Column Topic Topic Row Column HeaderImage Row Title Icon Description Row Topic Topic {
 ()
 {
 ()
 ()
 }
 ()
 {
 ()
 ()
 }
 } __ . (*). /\-| -;-| (*) |___

Slide 56

Slide 56 text

Header Image Title Icon Row Description down() Column Topic Topic Row Column HeaderImage Row Title Icon Description Row Topic Topic {
 ()
 {
 ()
 ()
 }
 ()
 {
 ()
 ()
 }
 } __ . (*). /\-| -;-| (*) |___

Slide 57

Slide 57 text

Header Image Title Icon Row Description Column Topic Topic Row Column HeaderImage Row Title Icon Description Row Topic Topic {
 ()
 {
 ()
 ()
 }
 ()
 {
 ()
 ()
 }
 } __ . (*). /\-| -;-| (*) |___

Slide 58

Slide 58 text

Header Image Title Icon Row Description Column Topic Topic Row Column HeaderImage Row Title Icon Description Row Topic Topic {
 ()
 {
 ()
 ()
 }
 ()
 {
 ()
 ()
 }
 } up() __ . (*). /\-| -;-| (*) |___

Slide 59

Slide 59 text

Header Image Title Icon Row Description Column Topic Topic Row Column HeaderImage Row Title Icon Description Row Topic Topic {
 ()
 {
 ()
 ()
 }
 ()
 {
 ()
 ()
 }
 } __ . (*). /\-| -;-| (*) |___

Slide 60

Slide 60 text

Header Image Title Icon Row Description Column Topic Topic Row Column HeaderImage Row Title Icon Description Row Topic Topic {
 ()
 {
 ()
 ()
 }
 ()
 {
 ()
 ()
 }
 } up() __ . (*). /\-| -;-| (*) |___

Slide 61

Slide 61 text

Column HeaderImage Row Title Icon Description Row Topic Topic {
 ()
 {
 ()
 ()
 }
 ()
 {
 ()
 ()
 }
 } Header Image Title Icon Row Description Column Topic Topic Row __ . (*). /\-| -;-| (*) |___

Slide 62

Slide 62 text

Description Header Image Title Row Icon Topic Topic Row Column __ . (*). /\-| -;-| (*) |___

Slide 63

Slide 63 text

Applier 컴포저블 노드를 트리 구조로 배치하고 순회하는 방법을 정의합니다. current: 현재 노드 down(): 현재 노드의 다음 자식 노드로 이동 insert(): 현재 노드에 자식 노드 추가 up(): 현재 노드의 바로 앞(위) 부모 노드로 이동 __ . (*). /\-| -;-| (*) |___

Slide 64

Slide 64 text

current: 현재 노드 down(): 현재 노드의 다음 자식 노드로 이동 up(): 현재 노드의 바로 앞(위) 부모 노드로 이동 insertTopDown(): 현재 노드에 하향식 방법으로 자식 노드 추가 insertBottomUp(): 현재 노드에 상향식 방법으로 자식 노드 추가 remove(): 특정 위치에 있는 노드 제거 move(): 특정 위치에 있는 노드를 다른 위치로 이동 clear(): 모든 노드 제거 Applier __ . (*). /\-| -;-| (*) |___

Slide 65

Slide 65 text

Compose Ui Applier -> UiApplie U 상향식인 insertBottomUp() 사용 Node -> LayoutNod4 LayoutNode#foldedChildren에 자식 노드 추 자식 노드도 LayoutNode로 동일 __ . (*). /\-| -;-| (*) |___

Slide 66

Slide 66 text

T opics Applier UI 노드 순회 담당 Recomposer UI 노드 새로고침 담당 Composition UI 노드 관리 담당 __ . (*). /\-| -;-| (*) |___

Slide 67

Slide 67 text

State의 변경이 감지되면, 
 해당 State를 읽는 LayoutNode의 새로고침을 예약합니다. Recomposer#runRecomposeAndApplyChanges Recomposer __ . (*). /\-| -;-| (*) |___

Slide 68

Slide 68 text

suspend fun while runRecomposeAndApplyChanges() { ( ) { awaitStateChanged() / whenNewFrameRequested { } } } shouldKeepRecomposing / State에 변경이 감지될 때까지 suspend로 대기 // 새로운 프레임이 요청될 때까지 suspend로 대기 // LayoutNode 새로고침 __ . (*). /\-| -;-| (*) |___

Slide 69

Slide 69 text

T opics Applier UI 노드 순회 담당 Recomposer UI 노드 새로고침 담당 Composition UI 노드 관리 담당 __ . (*). /\-| -;-| (*) |___

Slide 70

Slide 70 text

Applier가 작동할 트리를 생성하고, 생명주기에 맞게 트리 인스턴스를 관리합니다. Composition#setContent Composition __ . (*). /\-| -;-| (*) |___

Slide 71

Slide 71 text

Applier + Recomposer -> Composition // ComponentActivity#setContent의 최종 호출 함수 (요약됨) // Applier와 Recomposer를 사용하여 빈 트리 생성 // 생성된 트리에 first-composition 진행 (컴포저블 초기 상태 배치)
 fun val doSetContent(content: () -> Unit) { composition = Composition(UiApplier(), Recomposer()) composition.setContent(content) } @Composable __ . (*). /\-| -;-| (*) |___

Slide 72

Slide 72 text

composition.setContent { { ( ) ( ) { ( ) ( ) } } } < , > (factory: () -> ) {
 .startNode()
 .createNode(factory)
 .endNode()
 } // 모든 컴포저블이 결국 ComposeNode()로 Runtime에게 전달됨
 // insert(), down()
 // insert(), down(), up()
 // insert(), down(), up() // insert(), down() // insert(), down(), up() // insert(), down(), up() // up()
 // up() Column Text Text Row Text Text "Hello" "World!" "Jetpack" "Compose" @Composable fun Node Applier Node ComposeNode currentComposer currentComposer currentComposer __ . (*). /\-| -;-| (*) |___

Slide 73

Slide 73 text

Column {
 Text("Hello")
 Text("World!")
 Row {
 Text("Jetpack")
 Text("Compose")
 }
 } Column 루트 컴포저블인 Column으로 Composition 시작
 -> 초기 UI 트리 생성 __ . (*). /\-| -;-| (*) |___

Slide 74

Slide 74 text

Column Text {
 ( )
 "Hello" Text("World!")
 Row {
 Text("Jetpack")
 Text("Compose")
 }
 } Column “Hello“ __ . (*). /\-| -;-| (*) |___

Slide 75

Slide 75 text

Column “World!” “Hello“ Column Text Text {
 ( )
 ( )
 "Hello" "World!" Row {
 Text("Jetpack")
 Text("Compose")
 }
 } __ . (*). /\-| -;-| (*) |___

Slide 76

Slide 76 text

Column “World!” “Hello“ Row Column Text Text Row {
 ( )
 ( )
 "Hello" "World!" {
 Text("Jetpack")
 Text("Compose")
 }
 } __ . (*). /\-| -;-| (*) |___

Slide 77

Slide 77 text

Column “Jetpack” “World!” “Hello“ Row Column Text Text Row Text {
 ( )
 ( )
 {
 ( )
 "Hello" "World!" "Jetpack" Text("Compose")
 }
 } __ . (*). /\-| -;-| (*) |___

Slide 78

Slide 78 text

Column “Jetpack” “World!” “Hello“ “Compose” Row Column Text Text Row Text Text {
 ( )
 ( )
 {
 ( )
 ( )
 "Hello" "World!" "Jetpack" "Compose" }
 } __ . (*). /\-| -;-| (*) |___

Slide 79

Slide 79 text

Column “Jetpack” “World!” “Hello“ “Compose” Row Column Text Text Row Text Text {
 ( )
 ( )
 {
 ( )
 ( )
 }
 } "Hello" "World!" "Jetpack" "Compose" __ . (*). /\-| -;-| (*) |___

Slide 80

Slide 80 text

Column “Jetpack” “World!” “Hello“ “Compose” Row Hello World! Jetpack Compose __ . (*). /\-| -;-| (*) |___

Slide 81

Slide 81 text

여기까지가 Compose Runtime의 핵심 Applier 컴포저블 노드를 트리 구조로 배치하고
 순회하는 방법을 정의합니다. Recomposer State의 변경이 감지되면, 
 해당 State를 읽는 LayoutNode의
 새로고침을 예약합니다. Composition Applier가 작동할 트리를 생성하고, 생명주기에 맞게 트리 인스턴스를 관리합니다. __ . (*). /\-| -;-| (*) |___

Slide 82

Slide 82 text

Compose Runtime 매우 잘 설계된 노드 순회/관리 라이브러리 (안드로이드 의존 X) __ . (*). /\-| -;-| (*) |___

Slide 83

Slide 83 text

Compose Ui Runtime에서 관리하는 노드를 안드로이드 UI로 해석하는 라이브러리 __ . (*). /\-| -;-| (*) |___

Slide 84

Slide 84 text

나만의 Applier로 UI 라이브러리를 만들어 봅니다 Playing with the 
 Jetpack Compose Runtime __ . (*). /\-| -;-| (*) |___

Slide 85

Slide 85 text

TexÆ List (ordered) Hello Markdown! This is my list& $# First ite6 !# Second ite6 %# Third item Goodbye Markdown! __ . (*). /\-| -;-| (*) |___

Slide 86

Slide 86 text

이제 같이 해봐요 __ . (*). /\-| -;-| (*) |___

Slide 87

Slide 87 text

https://is.gd/2024cgt __ . (*). /\-| -;-| (*) |___

Slide 88

Slide 88 text

끝까지 함께 해주셔서 감사합니다! Finish \.-"-./ \( ^▼^)/ @ |‾‾‾‾‾| *|@ ///,\\.// ";-----, @|* \\\//.\\

Slide 89

Slide 89 text

https://is.gd/composeppt __ . (*). /\-| -;-| (*) |___

Slide 90

Slide 90 text

https://is.gd/composecli __ . (*). /\-| -;-| (*) |___

Slide 91

Slide 91 text

https://is.gd/composemd __ . (*). /\-| -;-| (*) |___

Slide 92

Slide 92 text

2024. 11. 02. (생각보다 쉬운) Kotlin Compiler Plugin으로 리컴포지션 추적기 만들기 이때도 와주실거죠?