Slide 1

Slide 1 text

Android 2024.4.22 Android Google LLC

Slide 2

Slide 2 text

©MIXI 2 2017 2023 Vantage D

Slide 3

Slide 3 text

No content

Slide 4

Slide 4 text

©MIXI 4 Android Android

Slide 5

Slide 5 text

No content

Slide 6

Slide 6 text

1 Android 2 3 UI 4 5 6 7 8 9 UI 10 Kotlin Multiplatform

Slide 7

Slide 7 text

Android 1

Slide 8

Slide 8 text

©MIXI Android 8 Android Auto Android TV PC ChromeOS Wear OS ,

Slide 9

Slide 9 text

©MIXI Android 9 API (SDK ) 2008.09 1.0 1 Base ... 2018.08 9 28 Pie 2019.09 10 29 Q 2020.09 11 30 R 2021.10 12 31 S 2022.03 12L 32 S v2 2022.08 13 33 Tiramisu 2023.10 14 34 UpsideDownCake - 15 35 VanillaIceCream API ( )

Slide 10

Slide 10 text

©MIXI Android Studio IntelliJ IDEA ⾒ https://developer.android.com/studio 10

Slide 11

Slide 11 text

©MIXI 11 Android Studio APK (Android Application Package) AVD (Android Virtual Device)

Slide 12

Slide 12 text

©MIXI 12 Android Studio AAB (Android App Bundle) Google Play

Slide 13

Slide 13 text

©MIXI 13 Android Studio AAB (Android App Bundle) Google Play : : xxhdpi CPU: arm : : hdpi CPU: x86 APK

Slide 14

Slide 14 text

©MIXI 14 Android Studio AAB (Android App Bundle) Google Play l l : : xxhdpi CPU: arm : : hdpi CPU: x86

Slide 15

Slide 15 text

©MIXI Kotlin Android (2017 ) Java 15 Kotlin l : l Java : Kotlin Java Java Kotlin l Null :

Slide 16

Slide 16 text

©MIXI l : l Java : Kotlin Java Java Kotlin l Null : Kotlin Android (2017 ) Java 16 Kotlin NullPointerException var count: Int // null var count: Int? // null

Slide 17

Slide 17 text

©MIXI Kotlin Android, iOS, Desktop, Web https://kotlinlang.org/docs/multiplatform.html 17 Kotlin Multiplatform Kotlin UI ( ) https://developerhttps://developer.android.com/develop/ui/compose?hl=ja Jetpack Compose

Slide 18

Slide 18 text

©MIXI Wear OS, ChromeOS, Android TV, Android Auto API : Android 14 API 34, UpsideDownCake APK : AAB : Google Play APK : , Java , Null Kotlin : Kotlin Multiplatform, Jetpack Compose 18 Android Kotlin

Slide 19

Slide 19 text

2

Slide 20

Slide 20 text

©MIXI Android Studio New Project 20

Slide 21

Slide 21 text

©MIXI Empty Activity (Activity ) Jetpack Compose 21

Slide 22

Slide 22 text

©MIXI Name Package name ID : example.co.jp jp.co.example Minimum SDK 22

Slide 23

Slide 23 text

©MIXI AVD ( ) ⾒ https://developer.android.com/studio/run/managing-avds?hl=ja 23 AVD

Slide 24

Slide 24 text

©MIXI 24 , , Kotlin ,

Slide 25

Slide 25 text

©MIXI ( ) 1. https://developer.android.com/studio/debug/dev-options?hl=ja#enable 2. USB ON 3. USB Android Studio 25 1. USB

Slide 26

Slide 26 text

©MIXI ( ) 1. Android 11 PC 2. https://developer.android.com/studio/debug/dev-options?hl=ja#enable 3. Android Studio Pair Devices Using Wi-Fi 4. ON 5. Android Studio 6. Android Studio 26 2. Wi-Fi

Slide 27

Slide 27 text

UI 3

Slide 28

Slide 28 text

©MIXI : 1. Android Studio Get from VCS 28 2. URL [email protected]:mixigroup/2024AndroidTraining.git git clone OK 3. app.ui 1

Slide 29

Slide 29 text

©MIXI Jetpack l l 29 app Android 14 Android 13 Android 12 if else if else ... app Android 14 Android 13 Android 12 Jetpack

Slide 30

Slide 30 text

©MIXI Jetpack Compose Jetpack Kotlin UI 2021 UI ( ) https://developer.android.com/develop/ui/compose?hl=ja 30

Slide 31

Slide 31 text

©MIXI 31 View : UI Compose : UI val textView = TextView(context) textView.setText("Hello") textView.setTextColor(Color.BLUE) Text( text = "Hello", color = Color.Blue, ) View UI View Composable UI Composable

Slide 32

Slide 32 text

©MIXI 32 View : UI Compose : UI val textView = TextView(context) textView.setText("Hello") textView.setTextColor(Color.BLUE) Text( text = "Hello", color = Color.Blue, ) Composable UI Composable UI Recompose

Slide 33

Slide 33 text

©MIXI Composable 33 @Composable fun RedText( text: String, modifier: Modifier = Modifier, ) { Text( text = text, modifier = modifier, color = Color.Red ) } RedText( text = "Red text", ) RedText( text = "Red text with blue background", modifier = Modifier.background(Color.Blue), )

Slide 34

Slide 34 text

©MIXI Composable 34 @Composable fun RedText( text: String, modifier: Modifier = Modifier, ) { Text( text = text, modifier = modifier, color = Color.Red, ) } Composable Compose Composable l ProfileScreen l LoginButton l HeaderImage

Slide 35

Slide 35 text

©MIXI Composable 35 // modifier RedText( text = "Red text", ) // modifier RedText( text = "Red text with blue background", modifier = Modifier.background(Color.Blue), ) text = modifier API

Slide 36

Slide 36 text

©MIXI Composable Composable Composable Composable e.g. Button, Tab, Snackbar 36 Snackbar { Text(text = "Hello") } Composable Snackbar: UI

Slide 37

Slide 37 text

©MIXI Composable 37 @Composable fun Snackbar( ... content: @Composable () -> Unit ) Snackbar(content = { Text(text = "Hello") }) Snackbar() { Text(text = "Hello") } Snackbar { Text(text = "Hello") } ( ) -> () -> Unit { -> } () ()

Slide 38

Slide 38 text

©MIXI Composable API ( ) 38 Snackbar( action = { ... }, content = { ... }, )

Slide 39

Slide 39 text

©MIXI Modifier.padding(all = 8.dp) Modifier.padding(horizontal = 8.dp, vertical = 4.dp) Modifier.padding(start = 8.dp, top = 4.dp, end = 8.dp, bottom = 16.dp) Modifier 39 // 96 x 48 dp Modifier.width(96.dp).height(48.dp) // 48 x 48 dp Modifier.size(48.dp) // Modifier.fillMaxWidth().wrapContentHeight() // Modifier.fillMaxSize() dp

Slide 40

Slide 40 text

©MIXI DP Px 40 DP : density-independent pixels : : : :

Slide 41

Slide 41 text

©MIXI 41 SP : scalable pixels

Slide 42

Slide 42 text

©MIXI Button, Checkbox, TopAppBar Composable 42 API https://developer.android.com/reference/kotlin/androidx/compose/material3/package-summary https://m3.material.io/components

Slide 43

Slide 43 text

©MIXI Composable Composable 43 Column Row

Slide 44

Slide 44 text

©MIXI Composable 44 Column( horizontalAlignment = Alignment.CenterHorizontally, verticalArrangement = Arrangement.spacedBy(8.dp), ) { Text(text = "Top") Text(text = "Center") Text(text = "Bottom") } Composable (36 )

Slide 45

Slide 45 text

©MIXI Composable Spacer 45 Column(horizontalAlignment = Alignment.CenterHorizontally) { Text(text = "Top") Spacer(modifier = Modifier.height(8.dp)) Text(text = "Center") Spacer(modifier = Modifier.height(8.dp)) Text(text = "Bottom") }

Slide 46

Slide 46 text

©MIXI 46 Column(modifier = modifier.height(160.dp)) { Text(text = "Top", modifier = Modifier.weight(1f)) Text(text = "Center") Text(text = "Bottom") } Column(modifier = modifier.height(160.dp)) { Text(text = "Top", modifier = Modifier.weight(1f)) Text(text = "Center", modifier = Modifier.weight(2f)) Text(text = "Bottom", modifier = Modifier.weight(3f)) } 1:2:3 ⾒

Slide 47

Slide 47 text

©MIXI Composable 47 Row( horizontalArrangement = Arrangement.spacedBy(8.dp), verticalAlignment = Alignment.CenterVertically, ) { Text(text = "Left") Text(text = "Center") Text(text = "Right") } Row : Column

Slide 48

Slide 48 text

©MIXI : LazyColumn Compose 48 Column LazyColumn Compose Item 1 Item 2 Item 3 Item 4 Item 5 Item 6 Item 7 Item 8 Item 1 Item 2 Item 3 Item 4 Item 5 Item 6 Item 7 Item 8 Compose

Slide 49

Slide 49 text

©MIXI LazyColumn LazyRow 49 LazyColumn( horizontalAlignment = Alignment.CenterHorizontally, verticalArrangement = Arrangement.spacedBy(8.dp), ) { // 1 item { Text(text = "Header") } // items(listOf("1", "2", "3")) { text -> Text(text = text) } }

Slide 50

Slide 50 text

©MIXI Composable @Preview 築 50

Slide 51

Slide 51 text

©MIXI 3.1 app.ui BookItem 52, 53 51 16 dp 8 dp 8 dp 4 dp 18 sp, 16 sp 16 dp title author

Slide 52

Slide 52 text

©MIXI 3.1 @Preview 52 app.ui UiScreen @Composable fun UiScreen(modifier: Modifier = Modifier) { Column(...) { ... val book = Book(title = " ", author = " ") BookItem(book = book) ... } } 1 2

Slide 53

Slide 53 text

©MIXI Android Studio Tips Option + Enter import 53 Unresolved reference Command + B Command +

Slide 54

Slide 54 text

©MIXI 3.2 ( ) API https://developer.android.com/reference/kotlin/androidx/compose/material3/package-summary 54

Slide 55

Slide 55 text

©MIXI UI 55 Jetpack UI Kotlin Jetpack Compose Composable UI Modifier Composable Column , Row , LazyColumn / LazyRow DP , SP

Slide 56

Slide 56 text

4

Slide 57

Slide 57 text

©MIXI Android 57 ( ) l String resource l Drawable resource l Raw resource src/main/res/

Slide 58

Slide 58 text

©MIXI res/values/strings.xml 58 ... Text(text = stringResource(id = R.string.login)) Text(text = stringResource(id = R.string.settings)) UI

Slide 59

Slide 59 text

©MIXI 59 strings.xml strings.xml 1 2

Slide 60

Slide 60 text

©MIXI 60 strings.xml Settings res/values/strings.xml res/values-ja/strings.xml

Slide 61

Slide 61 text

©MIXI 61 : JPG, PNG, WebP : SVG

Slide 62

Slide 62 text

©MIXI 62 res/drawable-mdpi/ res/drawable-hdpi/ res/drawable-xhdpi/ res/drawable-xxhdpi/ res/drawable-xxxhdpi/ res/drawable/ UI Android Studio VectorDrawable ( )

Slide 63

Slide 63 text

©MIXI VectorDrawable 63 SVG or

Slide 64

Slide 64 text

©MIXI Icon( painter = painterResource(id = R.drawable.ramen), contentDescription = stringResource(R.string.ramen), tint = Color.Red, ) 64 Image( painter = painterResource(id = R.drawable.ramen), contentDescription = stringResource(R.string.ramen), ) Icon

Slide 65

Slide 65 text

©MIXI Modifier 65 Image( ... modifier = Modifier.clip(CircleShape), ) Image( ... modifier = Modifier.clip(RoundedCornerShape(size = 8.dp)), )

Slide 66

Slide 66 text

©MIXI 4.1 3.1 BookItem 3.1 ⾒ answer/3.1

Slide 67

Slide 67 text

©MIXI 8dp padding 4.2 BookItem 67 16 dp 16 dp 48 x 48 dp l Android Studio l Modifier (35 ) l Modifier : https://developer.android.com/jetpack/compose/modifiers?hl=ja#order-modifier-matters

Slide 68

Slide 68 text

©MIXI 4.3 ( ) 4.1 https://developer.android.com/training/basics/supporting-devices/languages?hl=ja 68 l l

Slide 69

Slide 69 text

©MIXI 4.4 ( ) https://developer.android.com/develop/ui/compose/resources?hl=ja 69 l l l

Slide 70

Slide 70 text

©MIXI 70 res/values/strings.xml l l Android Studio VectorDrawable

Slide 71

Slide 71 text

5

Slide 72

Slide 72 text

©MIXI Text(text = " ") Composable (Recompose) UI 72 Text(text = " ")

Slide 73

Slide 73 text

©MIXI 73 0 1 1 2

Slide 74

Slide 74 text

©MIXI 1 : 74 var count = 0 Button(onClick = { count++ }) { Text(text = count.toString()) } count Recompose val : var : 0 0

Slide 75

Slide 75 text

©MIXI 1 : 75 var count by remember { mutableStateOf(0) } Button(onClick = { count++ }) { Text(text = count.toString()) } MutableState Compose Recompose (UI )

Slide 76

Slide 76 text

©MIXI 1 : 76 var count by remember { mutableStateOf(0) } Button(onClick = { count++ }) { Text(text = count.toString()) } Delegated property MutableState Int remember Recompose API : https://developer.android.com/jetpack/compose/state#state-in-composables

Slide 77

Slide 77 text

©MIXI 1 : 77 var count by remember { mutableStateOf(0) } Button(onClick = { count++ }) { Text(text = count.toString()) } 0 1

Slide 78

Slide 78 text

©MIXI var text by remember { mutableStateOf("") } TextField( value = text, onValueChange = { value -> text = value } ) 2 : 78

Slide 79

Slide 79 text

©MIXI 5.1 app.login LoginScreen l l ID 4 8 ( ) : userId.length 79

Slide 80

Slide 80 text

©MIXI 5.2 ( ) UI https://developer.android.com/reference/kotlin/androidx/compose/material3/package-summary 80 l Switch l Checkbox l Slider

Slide 81

Slide 81 text

©MIXI 81 Composable (Recompose) UI MutableState Recompose var state by remember { mutableStateOf( ) } UI Composable onClick onValueChange e.g. Button, TextField, Switch UI UI

Slide 82

Slide 82 text

6

Slide 83

Slide 83 text

©MIXI 83

Slide 84

Slide 84 text

©MIXI 84

Slide 85

Slide 85 text

©MIXI 85 1 2 3

Slide 86

Slide 86 text

©MIXI 86 :

Slide 87

Slide 87 text

©MIXI 87 val TAG = "LoginScreen" Log.v(TAG, " ") Log.d(TAG, " ") Log.i(TAG, " ") Log.w(TAG, " ") Log.e(TAG, " ") ( )

Slide 88

Slide 88 text

©MIXI package:mine 88 package: tag: Log level:

Slide 89

Slide 89 text

©MIXI 89 l l l l

Slide 90

Slide 90 text

7

Slide 91

Slide 91 text

©MIXI ( ) 91 A B A B l l UI l

Slide 92

Slide 92 text

©MIXI https://developer.android.com/topic/architecture?hl=ja 92 UI l UI l l UI l l UI l ( )

Slide 93

Slide 93 text

©MIXI 93 UI UI

Slide 94

Slide 94 text

©MIXI UI 94 UI UI Compose l UI l UI ViewModel l UI l UI UI

Slide 95

Slide 95 text

©MIXI 95 UI

Slide 96

Slide 96 text

©MIXI 96 UI Jetpack Room SQLite Jetpack DataStore Key-Value Ktor Kotlin Kotlin HTTP Retrofit HTTP

Slide 97

Slide 97 text

©MIXI 97 UI UI ( )

Slide 98

Slide 98 text

©MIXI : ver. 98 Column(...) { var result by remember { mutableStateOf("") } Text(text = result) Button(onClick = { result = listOf(" ", " ", ...).random() }) { Text(text = stringResource(R.string.pick_omikuji)) } }

Slide 99

Slide 99 text

©MIXI 99 UI l l ( ) l UI l

Slide 100

Slide 100 text

©MIXI ( ) 100 class OmikujiRepository { fun getResult(): String { return listOf(" ", " ", ...).random() } }

Slide 101

Slide 101 text

©MIXI UI 101 data class OmikujiUiState( val result: String = "", ) OK

Slide 102

Slide 102 text

©MIXI UI 102 data class OmikujiUiState( val result: String = "", ) : class OmikujiUiState( val result: String = "", ) { fun copy(result: String = this.result) = OmikujiUiState(result) override fun equals(other: Any?): Boolean { if (this === other) return true if (other !is OmikujiUiState) return false return result == other.result } override fun toString() = "ResultUiState(result='$result')" override fun hashCode() = result.hashCode() }

Slide 103

Slide 103 text

©MIXI Jetpack 103 class OmikujiViewModel() : ViewModel() { ... } UI ViewModel ViewModel

Slide 104

Slide 104 text

©MIXI ViewModel 104 class OmikujiViewModel( private val repository: OmikujiRepository = OmikujiRepository(), ) : ViewModel() { ... } (DI)

Slide 105

Slide 105 text

©MIXI UiState MutableState 105 class OmikujiViewModel(...) : ViewModel() { var uiState by mutableStateOf(OmikujiUiState()) } uiState = uiState.copy(result = " ")

Slide 106

Slide 106 text

©MIXI UiState ViewModel 106 class OmikujiViewModel(...) : ViewModel() { ... fun pick() { val result = repository.getResult() uiState = uiState.copy(result = result) } } UiState UI

Slide 107

Slide 107 text

©MIXI UI ViewModel 107 val viewModel: OmikujiViewModel = viewModel() val uiState = viewModel.uiState Text(text = uiState.result) var result by remember { mutableStateOf("") } Text(text = result) Before After Compose ViewModel

Slide 108

Slide 108 text

©MIXI Button(onClick = viewModel::pick) UI ViewModel 108 Button(onClick = { viewModel.pick() }) Button(onClick = { result = listOf(" ", " ", ...).random() }) Before After OK https://kotlinlang.org/docs/reflection.html#function-references

Slide 109

Slide 109 text

©MIXI 109 UI UI ViewModel app.omikuji

Slide 110

Slide 110 text

©MIXI 7.1 : ToDo 110

Slide 111

Slide 111 text

©MIXI 7.1 : ToDo app.todo 111 ToDoScreen ToDoViewModel uiState l l UI l UI l l ToDoUiState

Slide 112

Slide 112 text

©MIXI 7.2 ( ) 7.1 ToDo 112 1

Slide 113

Slide 113 text

©MIXI 7.3 ( ) https://developer.android.com/topic/architecture?hl=ja 113 l l UI l MutableState MutableStateFlow

Slide 114

Slide 114 text

©MIXI 114 , , Android l UI l UI UI l (DB ) ( )

Slide 115

Slide 115 text

8

Slide 116

Slide 116 text

©MIXI 116 UI ViewModel ( ) UI

Slide 117

Slide 117 text

©MIXI src/main/java/jp/co/mixi/androidtraining/omikuji/ui/OmikujiViewModel.kt 117 src/test/java/jp/co/mixi/androidtraining/omikuji/ui/OmikujiViewModelTest.kt ViewModel ViewModel Android Studio "Android" "Project"

Slide 118

Slide 118 text

©MIXI ViewModel 118 class OmikujiViewModelTest { private val viewModel = OmikujiViewModel() @Test fun testPick() { assertEquals("", viewModel.uiState.result) viewModel.pick() assertNotEquals("", viewModel.uiState.result) } }

Slide 119

Slide 119 text

©MIXI ViewModel 119 class OmikujiViewModelTest { private val viewModel = OmikujiViewModel() @Test fun testPick() { assertEquals("", viewModel.uiState.result) viewModel.pick() assertNotEquals("", viewModel.uiState.result) } } JUnit 4 (Java ) API

Slide 120

Slide 120 text

©MIXI ViewModel 120 class OmikujiViewModelTest { private val viewModel = OmikujiViewModel() @Test fun testPick() { assertEquals("", viewModel.uiState.result) viewModel.pick() assertNotEquals("", viewModel.uiState.result) } } uiState

Slide 121

Slide 121 text

©MIXI ViewModel 121 class OmikujiViewModelTest { private val viewModel = OmikujiViewModel() @Test fun testPick() { assertEquals("", viewModel.uiState.result) viewModel.pick() assertEquals(" ", viewModel.uiState.result) } }

Slide 122

Slide 122 text

©MIXI ViewModel 122 DefaultOmikujiRepository pick() ViewModel FakeOmikujiRepository pick()

Slide 123

Slide 123 text

©MIXI 123 class OmikujiViewModel( private val repository: OmikujiRepository, ) : ViewModel() DefaultOmikujiRepository FakeOmikujiRepository (104 )

Slide 124

Slide 124 text

©MIXI 124 interface OmikujiRepository { fun getResult(): String } class DefaultOmikujiRepository : OmikujiRepository { override fun getResult(): String { return listOf(" ", " ", ...).random() } } class FakeOmikujiRepository : OmikujiRepository { override fun getResult(): String { return " " } }

Slide 125

Slide 125 text

©MIXI 125 class OmikujiViewModelTest { private val viewModel = OmikujiViewModel(FakeOmikujiRepository()) @Test fun testPick() { assertEquals("", viewModel.uiState.result) viewModel.pick() assertEquals(" ", viewModel.uiState.result) } }

Slide 126

Slide 126 text

©MIXI 126

Slide 127

Slide 127 text

©MIXI Android Studio Tips 127 Option + Enter

Slide 128

Slide 128 text

©MIXI 8.1 7.1 ToDoViewModel 128 l l

Slide 129

Slide 129 text

©MIXI 8.2 ( ) UI Compose https://developer.android.com/develop/ui/compose/testing 129 https://developer.android.com/codelabs/jetpack-compose-testing Codelab

Slide 130

Slide 130 text

©MIXI 130 (Android ) UI : ViewModel, , : src/test/java/ : JUnit 4

Slide 131

Slide 131 text

9

Slide 132

Slide 132 text

©MIXI : 132

Slide 133

Slide 133 text

©MIXI 133 data class WeatherUiState( val weather: String = "", val isLoading: Boolean = false, ) fun getWeather() { // uiState = uiState.copy(isLoading = true) // val weather = repository.getWeather() // uiState = uiState.copy(weather = weather, isLoading = false) } ViewModel

Slide 134

Slide 134 text

©MIXI 134 data class WeatherUiState( val weather: String = "", val isLoading: Boolean = false ) fun getWeather() { // uiState = uiState.copy(isLoading = true) // val weather = repository.getWeather() // uiState = uiState.copy(weather = weather, isLoading = false) } ViewModel (UI )

Slide 135

Slide 135 text

©MIXI Kotlin 135 viewModelScope.launch { uiState = uiState.copy(isLoading = true) val weather = repository.getWeather() uiState = uiState.copy(weather = weather, isLoading = false) } uiState = uiState.copy(isLoading = true) val weather = repository.getWeather() uiState = uiState.copy(weather = weather, isLoading = false)

Slide 136

Slide 136 text

©MIXI Kotlin 136 viewModelScope.launch { uiState = uiState.copy(isLoading = true) val weather = repository.getWeather() uiState = uiState.copy(weather = weather, isLoading = false) } getWeather()

Slide 137

Slide 137 text

©MIXI 137 getWeather()

Slide 138

Slide 138 text

©MIXI 138 class WeatherRepository { suspend fun getWeather(): String { // } } suspend l suspend l suspend suspend

Slide 139

Slide 139 text

©MIXI suspend 139 Kotlin API delay(timeMillis = 2000) 2 Ktor (HTTP ) API val response = client.request(urlString = "https://...") DB Jetpack Room (SQLite ) API val user = dao.getUser(userId = ...)

Slide 140

Slide 140 text

©MIXI 140 viewModelScope.launch { val weather = repository.getWeather() } ViewModel viewModelScope ( )

Slide 141

Slide 141 text

©MIXI 9.1 : SNS app.sns app.weather 141 TimelineScreen TimelineViewModel TimelineUiState TimelineRepository List l l UiState l suspend

Slide 142

Slide 142 text

©MIXI 9.2 ( ) : SNS 9.1 ViewModel app.weather : https://developer.android.com/kotlin/coroutines/test?hl=ja 142 l l UiState

Slide 143

Slide 143 text

©MIXI 143 UI l l suspend l suspend l suspend l suspend suspend e.g. , DB

Slide 144

Slide 144 text

Kotlin Multiplatform 10

Slide 145

Slide 145 text

©MIXI 10.1 : Kotlin Multiplatform multiplatform Android / iOS / Desktop 145 https://www.jetbrains.com/help/kotlin-multiplatform-dev/compose-multiplatform-setup.html ü Xcode ü Kotlin Multiplatform Mobile plugin ü Xcode ü KDoctor

Slide 146

Slide 146 text

©MIXI 10.1 : Kotlin Multiplatform 146 ( ) iOS multiplatform

Slide 147

Slide 147 text

©MIXI 10.1 : Kotlin Multiplatform https://www.jetbrains.com/help/kotlin-multiplatform-dev/compose-multiplatform-create-first- app.html#run-on-a-new-ios-simulated-device 147 iOS

Slide 148

Slide 148 text

©MIXI 10.2 : Compose Multiplatform multiplatform TimelineScreen Compose Multiplatform https://www.jetbrains.com/ja-jp/lp/compose-multiplatform/ 148 l Android UI l l l

Slide 149

Slide 149 text

No content

Slide 150

Slide 150 text

©MIXI Compose, , , , https://github.com/android/nowinandroid 150 https://www.jetbrains.com/help/kotlin-multiplatform-dev/multiplatform-samples.html Compose UI https://github.com/android/compose-samples Now in Android App Kotlin Multiplatform Samples Jetpack Compose Samples

Slide 151

Slide 151 text

©MIXI https://android-developers.googleblog.com/ 151 https://medium.com/androiddevelopers https://material.io/blog/ Android Developers Blog Medium Material Design Blog https://blog.jetbrains.com/kotlin/ Kotlin Blog

Slide 152

Slide 152 text

No content