Slide 1

Slide 1 text

+FUQBDL$PNQPTF TakuSemba CyberAgent.Inc

Slide 2

Slide 2 text

@takusemba https://github.com/TakuSemba

Slide 3

Slide 3 text

+FUQBDL$PNQPTF

Slide 4

Slide 4 text

+FUQBDL$PNQPTF https://www.youtube.com/watch?v=VsStyq4Lzxo

Slide 5

Slide 5 text

@Composable fun Greeting(name: String) { Text ("Hello $name!") }

Slide 6

Slide 6 text

@Composable fun Greeting(name: String) { Text ("Hello $name!") }

Slide 7

Slide 7 text

No content

Slide 8

Slide 8 text

No content

Slide 9

Slide 9 text

What’s Composable

Slide 10

Slide 10 text

What’s Composable ɾA new set of Jetpack UI widgets

Slide 11

Slide 11 text

What’s Composable ɾA new set of Jetpack UI widgets ɾA kotlin compiler plugin

Slide 12

Slide 12 text

What’s Composable ɾA new set of Jetpack UI widgets ɾA kotlin compiler plugin ɾFully compatible with your existing app/code

Slide 13

Slide 13 text

What’s Composable ɾA new set of Jetpack UI widgets ɾA kotlin compiler plugin ɾFully compatible with your existing app/code ɾExperimental

Slide 14

Slide 14 text

@Composable

Slide 15

Slide 15 text

Text(“Hello world!”)

Slide 16

Slide 16 text

@Composable fun Greeting(name: String) { Text("Hello $name!") }

Slide 17

Slide 17 text

@Composable fun Greeting(name: String) { Text("Hello $name!") } class ComposeSampleActivity : Activity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) } }

Slide 18

Slide 18 text

@Composable fun Greeting(name: String) { Text("Hello $name!") } class ComposeSampleActivity : Activity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContent { CraneWrapper { Greeting("takusemba") } } } }

Slide 19

Slide 19 text

@Composable fun Greeting(name: String) { Text("Hello $name!") } class ComposeSampleActivity : Activity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContent { CraneWrapper { Greeting("takusemba") } } } }

Slide 20

Slide 20 text

@Composable fun Greeting(name: String) { Text("Hello $name!") } class ComposeSampleActivity : Activity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContent { CraneWrapper { Greeting("takusemba") } } } }

Slide 21

Slide 21 text

@Composable fun Greeting(name: String) { Text("Hello $name!") } class ComposeSampleActivity : Activity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContent { CraneWrapper { Greeting("takusemba") } } } }

Slide 22

Slide 22 text

class ComposeSampleActivity : Activity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContent { CraneWrapper { MaterialTheme { Greeting("takusemba") } } } } } @Composable fun Greeting(name: String) { Text("Hello $name!") }

Slide 23

Slide 23 text

@Composable fun Greeting(name: String) { Text(text = "Hello $name!", style = +themeTextStyle { h5 }) } class ComposeSampleActivity : Activity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContent { CraneWrapper { MaterialTheme { Greeting("takusemba") } } } } }

Slide 24

Slide 24 text

@Composable fun ScrollingList( data: List, body: @Composable()(T) -> Unit ) { // ... body(item) // ... }

Slide 25

Slide 25 text

@Composable fun ScrollingList( data: List, body: @Composable()(T) -> Unit ) { // ... body(item) // ... } @Composable fun NewsFeed(stories: List) { ScrollingList(stories) { story -> StoryWidget(story) } }

Slide 26

Slide 26 text

@Composable fun ScrollingList( data: List, body: @Composable()(T) -> Unit ) { // ... body(item) // ... } @Composable fun MenuList(items: List) { ScrollingList(items) { item -> when (item) { is FoodItem -> FoodWidget(item) is DrinkItem -> DrinkWidget(item) } } }

Slide 27

Slide 27 text

@Model

Slide 28

Slide 28 text

@Composable fun Greeting(name: String) { Text("Hello $name!") }

Slide 29

Slide 29 text

@Composable fun Greeting(name: String) { val count = +state { 0 } Column { Button(text = "greet", onClick = { count.value++ }) Text(text = "$name greeted ${count.value} times") } }

Slide 30

Slide 30 text

@Composable fun Greeting(name: String) { val count = +state { 0 } Column { Button(text = "greet", onClick = { count.value++ }) Text(text = "$name greeted ${count.value} times") } }

Slide 31

Slide 31 text

@Composable fun Greeting(name: String) { val count = +state { 0 } Column { Button(text = "greet", onClick = { count.value++ }) Text(text = "$name greeted ${count.value} times") } }

Slide 32

Slide 32 text

@Model class GreetCounter(var count: Int) { fun add() { count++ } fun substract() { count-- } } @Composable fun Greeting(name: String) { val count = +state { 0 } Column { Button(text = "greet", onClick = { count.value++ }) Text(text = "$name greeted ${count.value} times") } }

Slide 33

Slide 33 text

@Model class GreetCounter(var count: Int) { fun add() { count++ } fun substract() { count-- } } @Composable fun Greeting(name: String) { val counter = +memo { GreetCounter(0) } Column { Button(text = "greet", onClick = { count.add() }) Text(text = "$name greeted ${count.count} times") } }

Slide 34

Slide 34 text

@Composable fun Greeting(name: String) { val counter = +memo { GreetCounter(0) } Column { Button(text = "greet", onClick = { count.add() }) Text(text = "$name greeted ${count.count} times") } } @Model class GreetCounter(var count: Int) { fun add() { count++ } fun substract() { count-- } }

Slide 35

Slide 35 text

@Model class LoginState(var username: String, var password: String) { val valid: Boolean get() = username.isNotEmpty() && password.isNotEmpty() }

Slide 36

Slide 36 text

@Model class LoginState(var username: String, var password: String) { val valid: Boolean get() = username.isNotEmpty() && password.isNotEmpty() } @Composable fun LoginScreen(onClick: () -> Unit) { val model = +memo { LoginState() } EditText( text=model.username, onTextChange={ text -> model.username = text } ) EditText( text=model.password, onTextChange={ text -> model.password = text } ) Button(text="Login", enabled=model.valid, onClick={ onClick() }) }

Slide 37

Slide 37 text

@Model class LoginState(var username: String, var password: String) { val valid: Boolean get() = username.isNotEmpty() && password.isNotEmpty() } @Composable fun LoginScreen(onClick: () -> Unit) { val model = +memo { LoginState() } EditText( text=model.username, onTextChange={ text -> model.username = text } ) EditText( text=model.password, onTextChange={ text -> model.password = text } ) Button(text="Login", enabled=model.valid, onClick={ onClick() }) }

Slide 38

Slide 38 text

@GenerateView

Slide 39

Slide 39 text

@Composable fun Greeting(name: String) { Text ("Hello $name!") }

Slide 40

Slide 40 text

@Composable
 @GenerateView fun Greeting(name: String) { Text ("Hello $name!") }

Slide 41

Slide 41 text

@Composable
 @GenerateView fun Greeting(name: String) { Text ("Hello $name!") } // In your existing xml

Slide 42

Slide 42 text

@Composable
 @GenerateView fun Greeting(name: String) { Text ("Hello $name!") } // In your existing xml // find view by Id val greeting = findViewById(R.id.greeting)

Slide 43

Slide 43 text

@Discussion

Slide 44

Slide 44 text

No content

Slide 45

Slide 45 text

+FUQBDL$PNQPTF https://github.com/takusemba https://twitter.com/takusemba