Slide 1

Slide 1 text

Jetpack Compose for Games & Animations Wajahat Karim wajahatkarim.com WajahatKarim Google Dev Expert (GDE) in Android . Android Dev. Open Source Contributor . Technical Writer . Public Speaker 1

Slide 2

Slide 2 text

Jetpack Compose “ a modern UI toolkit which simplifies and accelerates UI development on Android with less code, powerful tools, and intuitive Kotlin APIs. d.android.com/jetpack/compose 2

Slide 3

Slide 3 text

Made with Jetpack Compose Alex Lockwood Gurupreet Singh 3

Slide 4

Slide 4 text

Animations in Jetpack Compose The animateContentSize() Modifier The AnimatedVisibility Composable Single Value Animations with animate() Repeated Animations with AnimatedValue Utilizing transitions to make solid animations 4

Slide 5

Slide 5 text

Animations in Jetpack Compose The animateContentSize() Modifier The AnimatedVisibility Composable Single Value Animations with animate() Repeated Animations with AnimatedValue Utilizing transitions to make solid animations 5

Slide 6

Slide 6 text

animateContentSize() Modifier @Composable fun ExpandableText() { val shortText = "Click me" val longText = "Very long text passage that spans \nacross multiple lines, paragraphs \nand pages" var short by remember { mutableStateOf(true) } Box( modifier = Modifier .background( Color.Blue, RoundedCornerShape(15.dp) ) .clickable { short = !short } .padding(20.dp) .wrapContentSize() .animateContentSize() ) { Text( if (short) { shortText } else { longText }, style = TextStyle(color = Color.White) ) } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 6

Slide 7

Slide 7 text

animateContentSize() Modifier @Composable fun ExpandableText() { val shortText = "Click me" val longText = "Very long text passage that spans \nacross multiple lines, paragraphs \nand pages" var short by remember { mutableStateOf(true) } Box( modifier = Modifier .background( Color.Blue, RoundedCornerShape(15.dp) ) .clickable { short = !short } .padding(20.dp) .wrapContentSize() .animateContentSize() ) { Text( if (short) { shortText } else { longText }, style = TextStyle(color = Color.White) ) } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 val shortText = "Click me" val longText = "Very long text passage that spans \nacross multiple lines, paragraphs \nand pages" @Composable 1 fun ExpandableText() { 2 3 4 5 6 var short by remember { mutableStateOf(true) } 7 Box( 8 modifier = Modifier 9 .background( 10 Color.Blue, 11 RoundedCornerShape(15.dp) 12 ) 13 .clickable { short = !short } 14 .padding(20.dp) 15 .wrapContentSize() 16 .animateContentSize() 17 ) { 18 Text( 19 if (short) { 20 shortText 21 } else { 22 longText 23 }, 24 style = TextStyle(color = Color.White) 25 ) 26 } 27 } 28 6

Slide 8

Slide 8 text

animateContentSize() Modifier @Composable fun ExpandableText() { val shortText = "Click me" val longText = "Very long text passage that spans \nacross multiple lines, paragraphs \nand pages" var short by remember { mutableStateOf(true) } Box( modifier = Modifier .background( Color.Blue, RoundedCornerShape(15.dp) ) .clickable { short = !short } .padding(20.dp) .wrapContentSize() .animateContentSize() ) { Text( if (short) { shortText } else { longText }, style = TextStyle(color = Color.White) ) } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 val shortText = "Click me" val longText = "Very long text passage that spans \nacross multiple lines, paragraphs \nand pages" @Composable 1 fun ExpandableText() { 2 3 4 5 6 var short by remember { mutableStateOf(true) } 7 Box( 8 modifier = Modifier 9 .background( 10 Color.Blue, 11 RoundedCornerShape(15.dp) 12 ) 13 .clickable { short = !short } 14 .padding(20.dp) 15 .wrapContentSize() 16 .animateContentSize() 17 ) { 18 Text( 19 if (short) { 20 shortText 21 } else { 22 longText 23 }, 24 style = TextStyle(color = Color.White) 25 ) 26 } 27 } 28 var short by remember { mutableStateOf(true) } .clickable { short = !short } if (short) { shortText } else { longText }, @Composable 1 fun ExpandableText() { 2 val shortText = "Click me" 3 val longText = "Very long text passage that spans 4 \nacross multiple lines, paragraphs 5 \nand pages" 6 7 Box( 8 modifier = Modifier 9 .background( 10 Color.Blue, 11 RoundedCornerShape(15.dp) 12 ) 13 14 .padding(20.dp) 15 .wrapContentSize() 16 .animateContentSize() 17 ) { 18 Text( 19 20 21 22 23 24 style = TextStyle(color = Color.White) 25 ) 26 } 27 } 28 6

Slide 9

Slide 9 text

animateContentSize() Modifier @Composable fun ExpandableText() { val shortText = "Click me" val longText = "Very long text passage that spans \nacross multiple lines, paragraphs \nand pages" var short by remember { mutableStateOf(true) } Box( modifier = Modifier .background( Color.Blue, RoundedCornerShape(15.dp) ) .clickable { short = !short } .padding(20.dp) .wrapContentSize() .animateContentSize() ) { Text( if (short) { shortText } else { longText }, style = TextStyle(color = Color.White) ) } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 val shortText = "Click me" val longText = "Very long text passage that spans \nacross multiple lines, paragraphs \nand pages" @Composable 1 fun ExpandableText() { 2 3 4 5 6 var short by remember { mutableStateOf(true) } 7 Box( 8 modifier = Modifier 9 .background( 10 Color.Blue, 11 RoundedCornerShape(15.dp) 12 ) 13 .clickable { short = !short } 14 .padding(20.dp) 15 .wrapContentSize() 16 .animateContentSize() 17 ) { 18 Text( 19 if (short) { 20 shortText 21 } else { 22 longText 23 }, 24 style = TextStyle(color = Color.White) 25 ) 26 } 27 } 28 var short by remember { mutableStateOf(true) } .clickable { short = !short } if (short) { shortText } else { longText }, @Composable 1 fun ExpandableText() { 2 val shortText = "Click me" 3 val longText = "Very long text passage that spans 4 \nacross multiple lines, paragraphs 5 \nand pages" 6 7 Box( 8 modifier = Modifier 9 .background( 10 Color.Blue, 11 RoundedCornerShape(15.dp) 12 ) 13 14 .padding(20.dp) 15 .wrapContentSize() 16 .animateContentSize() 17 ) { 18 Text( 19 20 21 22 23 24 style = TextStyle(color = Color.White) 25 ) 26 } 27 } 28 .animateContentSize() @Composable 1 fun ExpandableText() { 2 val shortText = "Click me" 3 val longText = "Very long text passage that spans 4 \nacross multiple lines, paragraphs 5 \nand pages" 6 var short by remember { mutableStateOf(true) } 7 Box( 8 modifier = Modifier 9 .background( 10 Color.Blue, 11 RoundedCornerShape(15.dp) 12 ) 13 .clickable { short = !short } 14 .padding(20.dp) 15 .wrapContentSize() 16 17 ) { 18 Text( 19 if (short) { 20 shortText 21 } else { 22 longText 23 }, 24 style = TextStyle(color = Color.White) 25 ) 26 } 27 } 28 6

Slide 10

Slide 10 text

animateContentSize() Modifier @Composable fun ExpandableText() { val shortText = "Click me" val longText = "Very long text passage that spans \nacross multiple lines, paragraphs \nand pages" var short by remember { mutableStateOf(true) } Box( modifier = Modifier .background( Color.Blue, RoundedCornerShape(15.dp) ) .clickable { short = !short } .padding(20.dp) .wrapContentSize() .animateContentSize() ) { Text( if (short) { shortText } else { longText }, style = TextStyle(color = Color.White) ) } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 val shortText = "Click me" val longText = "Very long text passage that spans \nacross multiple lines, paragraphs \nand pages" @Composable 1 fun ExpandableText() { 2 3 4 5 6 var short by remember { mutableStateOf(true) } 7 Box( 8 modifier = Modifier 9 .background( 10 Color.Blue, 11 RoundedCornerShape(15.dp) 12 ) 13 .clickable { short = !short } 14 .padding(20.dp) 15 .wrapContentSize() 16 .animateContentSize() 17 ) { 18 Text( 19 if (short) { 20 shortText 21 } else { 22 longText 23 }, 24 style = TextStyle(color = Color.White) 25 ) 26 } 27 } 28 var short by remember { mutableStateOf(true) } .clickable { short = !short } if (short) { shortText } else { longText }, @Composable 1 fun ExpandableText() { 2 val shortText = "Click me" 3 val longText = "Very long text passage that spans 4 \nacross multiple lines, paragraphs 5 \nand pages" 6 7 Box( 8 modifier = Modifier 9 .background( 10 Color.Blue, 11 RoundedCornerShape(15.dp) 12 ) 13 14 .padding(20.dp) 15 .wrapContentSize() 16 .animateContentSize() 17 ) { 18 Text( 19 20 21 22 23 24 style = TextStyle(color = Color.White) 25 ) 26 } 27 } 28 .animateContentSize() @Composable 1 fun ExpandableText() { 2 val shortText = "Click me" 3 val longText = "Very long text passage that spans 4 \nacross multiple lines, paragraphs 5 \nand pages" 6 var short by remember { mutableStateOf(true) } 7 Box( 8 modifier = Modifier 9 .background( 10 Color.Blue, 11 RoundedCornerShape(15.dp) 12 ) 13 .clickable { short = !short } 14 .padding(20.dp) 15 .wrapContentSize() 16 17 ) { 18 Text( 19 if (short) { 20 shortText 21 } else { 22 longText 23 }, 24 style = TextStyle(color = Color.White) 25 ) 26 } 27 } 28 @Composable fun ExpandableText() { val shortText = "Click me" val longText = "Very long text passage that spans \nacross multiple lines, paragraphs \nand pages" var short by remember { mutableStateOf(true) } Box( modifier = Modifier .background( Color.Blue, RoundedCornerShape(15.dp) ) .clickable { short = !short } .padding(20.dp) .wrapContentSize() .animateContentSize() ) { Text( if (short) { shortText } else { longText }, style = TextStyle(color = Color.White) ) } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 6

Slide 11

Slide 11 text

animateContentSize() Modifier @Composable fun PortraitModeImage() { var portraitMode by remember { mutableStateOf(true) } Box( Modifier.clickable { portraitMode = !portraitMode } .sizeIn(maxWidth = 300.dp, maxHeight = 300.dp) .background( if (portraitMode) Color(0xFFfffbd0) else Color( .animateContentSize( animSpec = tween(500, easing = LinearEasing), endListener = { startSize, endSize -> Log.d("droidcon", "$startSize -> $endSize") } ) .aspectRatio(if (portraitMode) 3 / 4f else 16 / 9f) ) { Text( if (portraitMode) { "3 : 4" } else { "16 : 9" }, style = TextStyle(color = Color.Black) ) } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 7

Slide 12

Slide 12 text

animateContentSize() Modifier @Composable fun PortraitModeImage() { var portraitMode by remember { mutableStateOf(true) } Box( Modifier.clickable { portraitMode = !portraitMode } .sizeIn(maxWidth = 300.dp, maxHeight = 300.dp) .background( if (portraitMode) Color(0xFFfffbd0) else Color( .animateContentSize( animSpec = tween(500, easing = LinearEasing), endListener = { startSize, endSize -> Log.d("droidcon", "$startSize -> $endSize") } ) .aspectRatio(if (portraitMode) 3 / 4f else 16 / 9f) ) { Text( if (portraitMode) { "3 : 4" } else { "16 : 9" }, style = TextStyle(color = Color.Black) ) } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 .animateContentSize( ) @Composable 1 fun PortraitModeImage() { 2 var portraitMode by remember { mutableStateOf(true) } 3 Box( 4 Modifier.clickable { portraitMode = !portraitMode } 5 .sizeIn(maxWidth = 300.dp, maxHeight = 300.dp) 6 .background( 7 if (portraitMode) Color(0xFFfffbd0) else Color( 8 9 animSpec = tween(500, easing = LinearEasing), 10 endListener = { startSize, endSize -> 11 Log.d("droidcon", "$startSize -> $endSize") 12 } 13 14 .aspectRatio(if (portraitMode) 3 / 4f else 16 / 9f) 15 ) { 16 Text( 17 if (portraitMode) { 18 "3 : 4" 19 } else { 20 "16 : 9" 21 }, 22 style = TextStyle(color = Color.Black) 23 ) 24 } 25 } 26 7

Slide 13

Slide 13 text

animateContentSize() Modifier @Composable fun PortraitModeImage() { var portraitMode by remember { mutableStateOf(true) } Box( Modifier.clickable { portraitMode = !portraitMode } .sizeIn(maxWidth = 300.dp, maxHeight = 300.dp) .background( if (portraitMode) Color(0xFFfffbd0) else Color( .animateContentSize( animSpec = tween(500, easing = LinearEasing), endListener = { startSize, endSize -> Log.d("droidcon", "$startSize -> $endSize") } ) .aspectRatio(if (portraitMode) 3 / 4f else 16 / 9f) ) { Text( if (portraitMode) { "3 : 4" } else { "16 : 9" }, style = TextStyle(color = Color.Black) ) } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 .animateContentSize( ) @Composable 1 fun PortraitModeImage() { 2 var portraitMode by remember { mutableStateOf(true) } 3 Box( 4 Modifier.clickable { portraitMode = !portraitMode } 5 .sizeIn(maxWidth = 300.dp, maxHeight = 300.dp) 6 .background( 7 if (portraitMode) Color(0xFFfffbd0) else Color( 8 9 animSpec = tween(500, easing = LinearEasing), 10 endListener = { startSize, endSize -> 11 Log.d("droidcon", "$startSize -> $endSize") 12 } 13 14 .aspectRatio(if (portraitMode) 3 / 4f else 16 / 9f) 15 ) { 16 Text( 17 if (portraitMode) { 18 "3 : 4" 19 } else { 20 "16 : 9" 21 }, 22 style = TextStyle(color = Color.Black) 23 ) 24 } 25 } 26 animSpec = tween(500, easing = LinearEasing), @Composable 1 fun PortraitModeImage() { 2 var portraitMode by remember { mutableStateOf(true) } 3 Box( 4 Modifier.clickable { portraitMode = !portraitMode } 5 .sizeIn(maxWidth = 300.dp, maxHeight = 300.dp) 6 .background( 7 if (portraitMode) Color(0xFFfffbd0) else Color( 8 .animateContentSize( 9 10 endListener = { startSize, endSize -> 11 Log.d("droidcon", "$startSize -> $endSize") 12 } 13 ) 14 .aspectRatio(if (portraitMode) 3 / 4f else 16 / 9f) 15 ) { 16 Text( 17 if (portraitMode) { 18 "3 : 4" 19 } else { 20 "16 : 9" 21 }, 22 style = TextStyle(color = Color.Black) 23 ) 24 } 25 } 26 7

Slide 14

Slide 14 text

animateContentSize() Modifier @Composable fun PortraitModeImage() { var portraitMode by remember { mutableStateOf(true) } Box( Modifier.clickable { portraitMode = !portraitMode } .sizeIn(maxWidth = 300.dp, maxHeight = 300.dp) .background( if (portraitMode) Color(0xFFfffbd0) else Color( .animateContentSize( animSpec = tween(500, easing = LinearEasing), endListener = { startSize, endSize -> Log.d("droidcon", "$startSize -> $endSize") } ) .aspectRatio(if (portraitMode) 3 / 4f else 16 / 9f) ) { Text( if (portraitMode) { "3 : 4" } else { "16 : 9" }, style = TextStyle(color = Color.Black) ) } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 .animateContentSize( ) @Composable 1 fun PortraitModeImage() { 2 var portraitMode by remember { mutableStateOf(true) } 3 Box( 4 Modifier.clickable { portraitMode = !portraitMode } 5 .sizeIn(maxWidth = 300.dp, maxHeight = 300.dp) 6 .background( 7 if (portraitMode) Color(0xFFfffbd0) else Color( 8 9 animSpec = tween(500, easing = LinearEasing), 10 endListener = { startSize, endSize -> 11 Log.d("droidcon", "$startSize -> $endSize") 12 } 13 14 .aspectRatio(if (portraitMode) 3 / 4f else 16 / 9f) 15 ) { 16 Text( 17 if (portraitMode) { 18 "3 : 4" 19 } else { 20 "16 : 9" 21 }, 22 style = TextStyle(color = Color.Black) 23 ) 24 } 25 } 26 animSpec = tween(500, easing = LinearEasing), @Composable 1 fun PortraitModeImage() { 2 var portraitMode by remember { mutableStateOf(true) } 3 Box( 4 Modifier.clickable { portraitMode = !portraitMode } 5 .sizeIn(maxWidth = 300.dp, maxHeight = 300.dp) 6 .background( 7 if (portraitMode) Color(0xFFfffbd0) else Color( 8 .animateContentSize( 9 10 endListener = { startSize, endSize -> 11 Log.d("droidcon", "$startSize -> $endSize") 12 } 13 ) 14 .aspectRatio(if (portraitMode) 3 / 4f else 16 / 9f) 15 ) { 16 Text( 17 if (portraitMode) { 18 "3 : 4" 19 } else { 20 "16 : 9" 21 }, 22 style = TextStyle(color = Color.Black) 23 ) 24 } 25 } 26 endListener = { startSize, endSize -> Log.d("droidcon", "$startSize -> $endSize") } @Composable 1 fun PortraitModeImage() { 2 var portraitMode by remember { mutableStateOf(true) } 3 Box( 4 Modifier.clickable { portraitMode = !portraitMode } 5 .sizeIn(maxWidth = 300.dp, maxHeight = 300.dp) 6 .background( 7 if (portraitMode) Color(0xFFfffbd0) else Color( 8 .animateContentSize( 9 animSpec = tween(500, easing = LinearEasing), 10 11 12 13 ) 14 .aspectRatio(if (portraitMode) 3 / 4f else 16 / 9f) 15 ) { 16 Text( 17 if (portraitMode) { 18 "3 : 4" 19 } else { 20 "16 : 9" 21 }, 22 style = TextStyle(color = Color.Black) 23 ) 24 } 25 } 26 7

Slide 15

Slide 15 text

Animations in Jetpack Compose The AnimatedVisibility Composable The animateContentSize() Modifier Single Value Animations with animate() Repeated Animations with AnimatedValue Utilizing transitions to make solid animations 8

Slide 16

Slide 16 text

AnimatedVisbility Composable @OptIn(ExperimentalAnimationApi::class) @Composable fun VisibilityAnimationFAB() { var expanded by remember { mutableStateOf(true) } FloatingActionButton( onClick = { expanded = !expanded }, ) { Row(Modifier.padding(start = 16.dp, end = 16.dp)) { Icon( asset = Icons.Default.Favorite, Modifier.align(Alignment.CenterVertically) ) AnimatedVisibility( expanded, modifier = Modifier.align(Alignment.CenterVertically) ) { Text(modifier = Modifier.padding(start = 8.dp), text = "Like") } } } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 9

Slide 17

Slide 17 text

AnimatedVisbility Composable @OptIn(ExperimentalAnimationApi::class) @Composable fun VisibilityAnimationFAB() { var expanded by remember { mutableStateOf(true) } FloatingActionButton( onClick = { expanded = !expanded }, ) { Row(Modifier.padding(start = 16.dp, end = 16.dp)) { Icon( asset = Icons.Default.Favorite, Modifier.align(Alignment.CenterVertically) ) AnimatedVisibility( expanded, modifier = Modifier.align(Alignment.CenterVertically) ) { Text(modifier = Modifier.padding(start = 8.dp), text = "Like") } } } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 @OptIn(ExperimentalAnimationApi::class) 1 @Composable 2 fun VisibilityAnimationFAB() { 3 var expanded by remember { mutableStateOf(true) } 4 FloatingActionButton( 5 onClick = { expanded = !expanded }, 6 ) { 7 Row(Modifier.padding(start = 16.dp, end = 16.dp)) { 8 Icon( 9 asset = Icons.Default.Favorite, 10 Modifier.align(Alignment.CenterVertically) 11 ) 12 AnimatedVisibility( 13 expanded, 14 modifier = Modifier.align(Alignment.CenterVertically) 15 ) { 16 Text(modifier = Modifier.padding(start = 8.dp), text = "Like") 17 } 18 } 19 } 20 } 21 9

Slide 18

Slide 18 text

AnimatedVisbility Composable @OptIn(ExperimentalAnimationApi::class) @Composable fun VisibilityAnimationFAB() { var expanded by remember { mutableStateOf(true) } FloatingActionButton( onClick = { expanded = !expanded }, ) { Row(Modifier.padding(start = 16.dp, end = 16.dp)) { Icon( asset = Icons.Default.Favorite, Modifier.align(Alignment.CenterVertically) ) AnimatedVisibility( expanded, modifier = Modifier.align(Alignment.CenterVertically) ) { Text(modifier = Modifier.padding(start = 8.dp), text = "Like") } } } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 @OptIn(ExperimentalAnimationApi::class) 1 @Composable 2 fun VisibilityAnimationFAB() { 3 var expanded by remember { mutableStateOf(true) } 4 FloatingActionButton( 5 onClick = { expanded = !expanded }, 6 ) { 7 Row(Modifier.padding(start = 16.dp, end = 16.dp)) { 8 Icon( 9 asset = Icons.Default.Favorite, 10 Modifier.align(Alignment.CenterVertically) 11 ) 12 AnimatedVisibility( 13 expanded, 14 modifier = Modifier.align(Alignment.CenterVertically) 15 ) { 16 Text(modifier = Modifier.padding(start = 8.dp), text = "Like") 17 } 18 } 19 } 20 } 21 FloatingActionButton( onClick = { expanded = !expanded }, ) { Row(Modifier.padding(start = 16.dp, end = 16.dp)) { Icon( Text(modifier = Modifier.padding(start = 8.dp), text = "Like") } } @OptIn(ExperimentalAnimationApi::class) 1 @Composable 2 fun VisibilityAnimationFAB() { 3 var expanded by remember { mutableStateOf(true) } 4 5 6 7 8 9 asset = Icons.Default.Favorite, 10 Modifier.align(Alignment.CenterVertically) 11 ) 12 AnimatedVisibility( 13 expanded, 14 modifier = Modifier.align(Alignment.CenterVertically) 15 ) { 16 17 } 18 19 20 } 21 9

Slide 19

Slide 19 text

AnimatedVisbility Composable @OptIn(ExperimentalAnimationApi::class) @Composable fun VisibilityAnimationFAB() { var expanded by remember { mutableStateOf(true) } FloatingActionButton( onClick = { expanded = !expanded }, ) { Row(Modifier.padding(start = 16.dp, end = 16.dp)) { Icon( asset = Icons.Default.Favorite, Modifier.align(Alignment.CenterVertically) ) AnimatedVisibility( expanded, modifier = Modifier.align(Alignment.CenterVertically) ) { Text(modifier = Modifier.padding(start = 8.dp), text = "Like") } } } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 @OptIn(ExperimentalAnimationApi::class) 1 @Composable 2 fun VisibilityAnimationFAB() { 3 var expanded by remember { mutableStateOf(true) } 4 FloatingActionButton( 5 onClick = { expanded = !expanded }, 6 ) { 7 Row(Modifier.padding(start = 16.dp, end = 16.dp)) { 8 Icon( 9 asset = Icons.Default.Favorite, 10 Modifier.align(Alignment.CenterVertically) 11 ) 12 AnimatedVisibility( 13 expanded, 14 modifier = Modifier.align(Alignment.CenterVertically) 15 ) { 16 Text(modifier = Modifier.padding(start = 8.dp), text = "Like") 17 } 18 } 19 } 20 } 21 FloatingActionButton( onClick = { expanded = !expanded }, ) { Row(Modifier.padding(start = 16.dp, end = 16.dp)) { Icon( Text(modifier = Modifier.padding(start = 8.dp), text = "Like") } } @OptIn(ExperimentalAnimationApi::class) 1 @Composable 2 fun VisibilityAnimationFAB() { 3 var expanded by remember { mutableStateOf(true) } 4 5 6 7 8 9 asset = Icons.Default.Favorite, 10 Modifier.align(Alignment.CenterVertically) 11 ) 12 AnimatedVisibility( 13 expanded, 14 modifier = Modifier.align(Alignment.CenterVertically) 15 ) { 16 17 } 18 19 20 } 21 AnimatedVisibility( @OptIn(ExperimentalAnimationApi::class) 1 @Composable 2 fun VisibilityAnimationFAB() { 3 var expanded by remember { mutableStateOf(true) } 4 FloatingActionButton( 5 onClick = { expanded = !expanded }, 6 ) { 7 Row(Modifier.padding(start = 16.dp, end = 16.dp)) { 8 Icon( 9 asset = Icons.Default.Favorite, 10 Modifier.align(Alignment.CenterVertically) 11 ) 12 13 expanded, 14 modifier = Modifier.align(Alignment.CenterVertically) 15 ) { 16 Text(modifier = Modifier.padding(start = 8.dp), text = "Like") 17 } 18 } 19 } 20 } 21 9

Slide 20

Slide 20 text

AnimatedVisbility Composable @OptIn(ExperimentalAnimationApi::class) @Composable fun VisibilityAnimationFAB() { var expanded by remember { mutableStateOf(true) } FloatingActionButton( onClick = { expanded = !expanded }, ) { Row(Modifier.padding(start = 16.dp, end = 16.dp)) { Icon( asset = Icons.Default.Favorite, Modifier.align(Alignment.CenterVertically) ) AnimatedVisibility( expanded, modifier = Modifier.align(Alignment.CenterVertically) ) { Text(modifier = Modifier.padding(start = 8.dp), text = "Like") } } } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 @OptIn(ExperimentalAnimationApi::class) 1 @Composable 2 fun VisibilityAnimationFAB() { 3 var expanded by remember { mutableStateOf(true) } 4 FloatingActionButton( 5 onClick = { expanded = !expanded }, 6 ) { 7 Row(Modifier.padding(start = 16.dp, end = 16.dp)) { 8 Icon( 9 asset = Icons.Default.Favorite, 10 Modifier.align(Alignment.CenterVertically) 11 ) 12 AnimatedVisibility( 13 expanded, 14 modifier = Modifier.align(Alignment.CenterVertically) 15 ) { 16 Text(modifier = Modifier.padding(start = 8.dp), text = "Like") 17 } 18 } 19 } 20 } 21 FloatingActionButton( onClick = { expanded = !expanded }, ) { Row(Modifier.padding(start = 16.dp, end = 16.dp)) { Icon( Text(modifier = Modifier.padding(start = 8.dp), text = "Like") } } @OptIn(ExperimentalAnimationApi::class) 1 @Composable 2 fun VisibilityAnimationFAB() { 3 var expanded by remember { mutableStateOf(true) } 4 5 6 7 8 9 asset = Icons.Default.Favorite, 10 Modifier.align(Alignment.CenterVertically) 11 ) 12 AnimatedVisibility( 13 expanded, 14 modifier = Modifier.align(Alignment.CenterVertically) 15 ) { 16 17 } 18 19 20 } 21 AnimatedVisibility( @OptIn(ExperimentalAnimationApi::class) 1 @Composable 2 fun VisibilityAnimationFAB() { 3 var expanded by remember { mutableStateOf(true) } 4 FloatingActionButton( 5 onClick = { expanded = !expanded }, 6 ) { 7 Row(Modifier.padding(start = 16.dp, end = 16.dp)) { 8 Icon( 9 asset = Icons.Default.Favorite, 10 Modifier.align(Alignment.CenterVertically) 11 ) 12 13 expanded, 14 modifier = Modifier.align(Alignment.CenterVertically) 15 ) { 16 Text(modifier = Modifier.padding(start = 8.dp), text = "Like") 17 } 18 } 19 } 20 } 21 var expanded by remember { mutableStateOf(true) } onClick = { expanded = !expanded }, expanded, @OptIn(ExperimentalAnimationApi::class) 1 @Composable 2 fun VisibilityAnimationFAB() { 3 4 FloatingActionButton( 5 6 ) { 7 Row(Modifier.padding(start = 16.dp, end = 16.dp)) { 8 Icon( 9 asset = Icons.Default.Favorite, 10 Modifier.align(Alignment.CenterVertically) 11 ) 12 AnimatedVisibility( 13 14 modifier = Modifier.align(Alignment.CenterVertically) 15 ) { 16 Text(modifier = Modifier.padding(start = 8.dp), text = "Like") 17 } 18 } 19 } 20 } 21 9

Slide 21

Slide 21 text

AnimatedVisbility Composable @OptIn(ExperimentalAnimationApi::class) @Composable fun VisibilityAnimationFAB() { var expanded by remember { mutableStateOf(true) } FloatingActionButton( onClick = { expanded = !expanded }, ) { Row(Modifier.padding(start = 16.dp, end = 16.dp)) { Icon( asset = Icons.Default.Favorite, Modifier.align(Alignment.CenterVertically) ) AnimatedVisibility( expanded, modifier = Modifier.align(Alignment.CenterVertically), enter = slideInHorizontally( initialOffsetX = { 300 }, animSpec = tween(durationMillis = 2000) ), exit = slideOutVertically( targetOffsetY = { 100 }, animSpec = tween(durationMillis = 2000) ) ) { Text(text = "Like") } } } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 Default Enter Enter + Exit 10

Slide 22

Slide 22 text

AnimatedVisbility Composable @OptIn(ExperimentalAnimationApi::class) @Composable fun VisibilityAnimationFAB() { var expanded by remember { mutableStateOf(true) } FloatingActionButton( onClick = { expanded = !expanded }, ) { Row(Modifier.padding(start = 16.dp, end = 16.dp)) { Icon( asset = Icons.Default.Favorite, Modifier.align(Alignment.CenterVertically) ) AnimatedVisibility( expanded, modifier = Modifier.align(Alignment.CenterVertically), enter = slideInHorizontally( initialOffsetX = { 300 }, animSpec = tween(durationMillis = 2000) ), exit = slideOutVertically( targetOffsetY = { 100 }, animSpec = tween(durationMillis = 2000) ) ) { Text(text = "Like") } } } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 enter = slideInHorizontally( initialOffsetX = { 300 }, animSpec = tween(durationMillis = 2000) ), @OptIn(ExperimentalAnimationApi::class) 1 @Composable 2 fun VisibilityAnimationFAB() { 3 var expanded by remember { mutableStateOf(true) } 4 FloatingActionButton( 5 onClick = { expanded = !expanded }, 6 ) { 7 Row(Modifier.padding(start = 16.dp, end = 16.dp)) { 8 Icon( 9 asset = Icons.Default.Favorite, 10 Modifier.align(Alignment.CenterVertically) 11 ) 12 AnimatedVisibility( 13 expanded, 14 modifier = Modifier.align(Alignment.CenterVertically), 15 16 17 18 19 exit = slideOutVertically( 20 targetOffsetY = { 100 }, 21 animSpec = tween(durationMillis = 2000) 22 ) 23 ) { 24 Text(text = "Like") 25 } 26 } 27 } 28 } 29 Default Enter Enter + Exit 10

Slide 23

Slide 23 text

AnimatedVisbility Composable @OptIn(ExperimentalAnimationApi::class) @Composable fun VisibilityAnimationFAB() { var expanded by remember { mutableStateOf(true) } FloatingActionButton( onClick = { expanded = !expanded }, ) { Row(Modifier.padding(start = 16.dp, end = 16.dp)) { Icon( asset = Icons.Default.Favorite, Modifier.align(Alignment.CenterVertically) ) AnimatedVisibility( expanded, modifier = Modifier.align(Alignment.CenterVertically), enter = slideInHorizontally( initialOffsetX = { 300 }, animSpec = tween(durationMillis = 2000) ), exit = slideOutVertically( targetOffsetY = { 100 }, animSpec = tween(durationMillis = 2000) ) ) { Text(text = "Like") } } } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 enter = slideInHorizontally( initialOffsetX = { 300 }, animSpec = tween(durationMillis = 2000) ), @OptIn(ExperimentalAnimationApi::class) 1 @Composable 2 fun VisibilityAnimationFAB() { 3 var expanded by remember { mutableStateOf(true) } 4 FloatingActionButton( 5 onClick = { expanded = !expanded }, 6 ) { 7 Row(Modifier.padding(start = 16.dp, end = 16.dp)) { 8 Icon( 9 asset = Icons.Default.Favorite, 10 Modifier.align(Alignment.CenterVertically) 11 ) 12 AnimatedVisibility( 13 expanded, 14 modifier = Modifier.align(Alignment.CenterVertically), 15 16 17 18 19 exit = slideOutVertically( 20 targetOffsetY = { 100 }, 21 animSpec = tween(durationMillis = 2000) 22 ) 23 ) { 24 Text(text = "Like") 25 } 26 } 27 } 28 } 29 exit = slideOutVertically( targetOffsetY = { 100 }, animSpec = tween(durationMillis = 2000) ) @OptIn(ExperimentalAnimationApi::class) 1 @Composable 2 fun VisibilityAnimationFAB() { 3 var expanded by remember { mutableStateOf(true) } 4 FloatingActionButton( 5 onClick = { expanded = !expanded }, 6 ) { 7 Row(Modifier.padding(start = 16.dp, end = 16.dp)) { 8 Icon( 9 asset = Icons.Default.Favorite, 10 Modifier.align(Alignment.CenterVertically) 11 ) 12 AnimatedVisibility( 13 expanded, 14 modifier = Modifier.align(Alignment.CenterVertically), 15 enter = slideInHorizontally( 16 initialOffsetX = { 300 }, 17 animSpec = tween(durationMillis = 2000) 18 ), 19 20 21 22 23 ) { 24 Text(text = "Like") 25 } 26 } 27 } 28 } 29 Default Enter Enter + Exit 10

Slide 24

Slide 24 text

AnimatedVisbility Composable cs.android.com AnimatedVisibility in LazyColumn AnimatedVisibility in multiple Composables 11

Slide 25

Slide 25 text

Animations in Jetpack Compose Single Value Animations with animate() The animateContentSize() Modifier The AnimatedVisibility Composable Single Value Animations with animate() Repeated Animations with AnimatedValue Utilizing transitions to make solid animations 12

Slide 26

Slide 26 text

@Composable fun ScaleAndColorAnimation() { val enabled = remember { mutableStateOf(true) } val color = if (enabled.value) MaterialTheme.colors.primary else MaterialTheme.colors.secondary val height = if (enabled.value) 40.dp else 60.dp val width = if (enabled.value) 150.dp else 300.dp Button( onClick = { enabled.value = !enabled.value }, backgroundColor = animate(color), modifier = Modifier .padding(16.dp) .preferredHeight(animate(height)) .preferredWidth(animate(width)), ) { Text("Scale & Color") } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 The animate() A simple method for animations between current and target state. Supports Int, Dp, Color, Rect and many more types. 13

Slide 27

Slide 27 text

@Composable fun ScaleAndColorAnimation() { val enabled = remember { mutableStateOf(true) } val color = if (enabled.value) MaterialTheme.colors.primary else MaterialTheme.colors.secondary val height = if (enabled.value) 40.dp else 60.dp val width = if (enabled.value) 150.dp else 300.dp Button( onClick = { enabled.value = !enabled.value }, backgroundColor = animate(color), modifier = Modifier .padding(16.dp) .preferredHeight(animate(height)) .preferredWidth(animate(width)), ) { Text("Scale & Color") } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 val color = if (enabled.value) MaterialTheme.colors.primary else MaterialTheme.colors.secondary val height = if (enabled.value) 40.dp else 60.dp val width = if (enabled.value) 150.dp else 300.dp @Composable 1 fun ScaleAndColorAnimation() { 2 val enabled = remember { mutableStateOf(true) } 3 4 5 6 7 8 9 Button( 10 onClick = { enabled.value = !enabled.value }, 11 backgroundColor = animate(color), 12 modifier = Modifier 13 .padding(16.dp) 14 .preferredHeight(animate(height)) 15 .preferredWidth(animate(width)), 16 ) { 17 Text("Scale & Color") 18 } 19 } 20 The animate() A simple method for animations between current and target state. Supports Int, Dp, Color, Rect and many more types. 13

Slide 28

Slide 28 text

@Composable fun ScaleAndColorAnimation() { val enabled = remember { mutableStateOf(true) } val color = if (enabled.value) MaterialTheme.colors.primary else MaterialTheme.colors.secondary val height = if (enabled.value) 40.dp else 60.dp val width = if (enabled.value) 150.dp else 300.dp Button( onClick = { enabled.value = !enabled.value }, backgroundColor = animate(color), modifier = Modifier .padding(16.dp) .preferredHeight(animate(height)) .preferredWidth(animate(width)), ) { Text("Scale & Color") } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 val color = if (enabled.value) MaterialTheme.colors.primary else MaterialTheme.colors.secondary val height = if (enabled.value) 40.dp else 60.dp val width = if (enabled.value) 150.dp else 300.dp @Composable 1 fun ScaleAndColorAnimation() { 2 val enabled = remember { mutableStateOf(true) } 3 4 5 6 7 8 9 Button( 10 onClick = { enabled.value = !enabled.value }, 11 backgroundColor = animate(color), 12 modifier = Modifier 13 .padding(16.dp) 14 .preferredHeight(animate(height)) 15 .preferredWidth(animate(width)), 16 ) { 17 Text("Scale & Color") 18 } 19 } 20 backgroundColor = animate(color), @Composable 1 fun ScaleAndColorAnimation() { 2 val enabled = remember { mutableStateOf(true) } 3 val color = if (enabled.value) MaterialTheme.colors.primary 4 else MaterialTheme.colors.secondary 5 6 val height = if (enabled.value) 40.dp else 60.dp 7 val width = if (enabled.value) 150.dp else 300.dp 8 9 Button( 10 onClick = { enabled.value = !enabled.value }, 11 12 modifier = Modifier 13 .padding(16.dp) 14 .preferredHeight(animate(height)) 15 .preferredWidth(animate(width)), 16 ) { 17 Text("Scale & Color") 18 } 19 } 20 The animate() A simple method for animations between current and target state. Supports Int, Dp, Color, Rect and many more types. 13

Slide 29

Slide 29 text

@Composable fun ScaleAndColorAnimation() { val enabled = remember { mutableStateOf(true) } val color = if (enabled.value) MaterialTheme.colors.primary else MaterialTheme.colors.secondary val height = if (enabled.value) 40.dp else 60.dp val width = if (enabled.value) 150.dp else 300.dp Button( onClick = { enabled.value = !enabled.value }, backgroundColor = animate(color), modifier = Modifier .padding(16.dp) .preferredHeight(animate(height)) .preferredWidth(animate(width)), ) { Text("Scale & Color") } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 val color = if (enabled.value) MaterialTheme.colors.primary else MaterialTheme.colors.secondary val height = if (enabled.value) 40.dp else 60.dp val width = if (enabled.value) 150.dp else 300.dp @Composable 1 fun ScaleAndColorAnimation() { 2 val enabled = remember { mutableStateOf(true) } 3 4 5 6 7 8 9 Button( 10 onClick = { enabled.value = !enabled.value }, 11 backgroundColor = animate(color), 12 modifier = Modifier 13 .padding(16.dp) 14 .preferredHeight(animate(height)) 15 .preferredWidth(animate(width)), 16 ) { 17 Text("Scale & Color") 18 } 19 } 20 backgroundColor = animate(color), @Composable 1 fun ScaleAndColorAnimation() { 2 val enabled = remember { mutableStateOf(true) } 3 val color = if (enabled.value) MaterialTheme.colors.primary 4 else MaterialTheme.colors.secondary 5 6 val height = if (enabled.value) 40.dp else 60.dp 7 val width = if (enabled.value) 150.dp else 300.dp 8 9 Button( 10 onClick = { enabled.value = !enabled.value }, 11 12 modifier = Modifier 13 .padding(16.dp) 14 .preferredHeight(animate(height)) 15 .preferredWidth(animate(width)), 16 ) { 17 Text("Scale & Color") 18 } 19 } 20 .preferredHeight(animate(height)) .preferredWidth(animate(width)), @Composable 1 fun ScaleAndColorAnimation() { 2 val enabled = remember { mutableStateOf(true) } 3 val color = if (enabled.value) MaterialTheme.colors.primary 4 else MaterialTheme.colors.secondary 5 6 val height = if (enabled.value) 40.dp else 60.dp 7 val width = if (enabled.value) 150.dp else 300.dp 8 9 Button( 10 onClick = { enabled.value = !enabled.value }, 11 backgroundColor = animate(color), 12 modifier = Modifier 13 .padding(16.dp) 14 15 16 ) { 17 Text("Scale & Color") 18 } 19 } 20 The animate() A simple method for animations between current and target state. Supports Int, Dp, Color, Rect and many more types. 13

Slide 30

Slide 30 text

@Composable fun GenderSelectAnimation() { val female = remember { mutableStateOf(true) } Row(horizontalArrangement = Arrangement.Center, modifier = Modifier.padding(8.dp).fillMaxWidth(), verticalAlignment = Alignment.CenterVertically ) { Image( asset = imageResource(R.drawable.male), contentScale = ContentScale.Crop, modifier = Modifier .preferredSize(animate(if (female.value) 100.dp else 250.dp)) .border(width = animate(if (female.value) 0.dp else 4.dp), color = animate(if (female.value) Color.Transparent else Color.Red)) .padding(8.dp) .clickable { female.value = !female.value } .clip(RoundedCornerShape(animate(if (female.value) 0.dp else 8.dp))) ) Image( asset = imageResource(R.drawable.female), contentScale = ContentScale.Crop, modifier = Modifier // ... // Like previous image ) } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 The animate() 14

Slide 31

Slide 31 text

@Composable fun GenderSelectAnimation() { val female = remember { mutableStateOf(true) } Row(horizontalArrangement = Arrangement.Center, modifier = Modifier.padding(8.dp).fillMaxWidth(), verticalAlignment = Alignment.CenterVertically ) { Image( asset = imageResource(R.drawable.male), contentScale = ContentScale.Crop, modifier = Modifier .preferredSize(animate(if (female.value) 100.dp else 250.dp)) .border(width = animate(if (female.value) 0.dp else 4.dp), color = animate(if (female.value) Color.Transparent else Color.Red)) .padding(8.dp) .clickable { female.value = !female.value } .clip(RoundedCornerShape(animate(if (female.value) 0.dp else 8.dp))) ) Image( asset = imageResource(R.drawable.female), contentScale = ContentScale.Crop, modifier = Modifier // ... // Like previous image ) } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 val female = remember { mutableStateOf(true) } .clickable { female.value = !female.value } @Composable 1 fun GenderSelectAnimation() { 2 3 Row(horizontalArrangement = Arrangement.Center, 4 modifier = Modifier.padding(8.dp).fillMaxWidth(), 5 verticalAlignment = Alignment.CenterVertically 6 ) { 7 Image( 8 asset = imageResource(R.drawable.male), 9 contentScale = ContentScale.Crop, 10 modifier = Modifier 11 .preferredSize(animate(if (female.value) 100.dp else 250.dp)) 12 .border(width = animate(if (female.value) 0.dp else 4.dp), 13 color = animate(if (female.value) Color.Transparent else Color.Red)) 14 .padding(8.dp) 15 16 .clip(RoundedCornerShape(animate(if (female.value) 0.dp else 8.dp))) 17 ) 18 Image( 19 asset = imageResource(R.drawable.female), 20 contentScale = ContentScale.Crop, 21 modifier = Modifier 22 // ... 23 // Like previous image 24 ) 25 } 26 } 27 The animate() 14

Slide 32

Slide 32 text

@Composable fun GenderSelectAnimation() { val female = remember { mutableStateOf(true) } Row(horizontalArrangement = Arrangement.Center, modifier = Modifier.padding(8.dp).fillMaxWidth(), verticalAlignment = Alignment.CenterVertically ) { Image( asset = imageResource(R.drawable.male), contentScale = ContentScale.Crop, modifier = Modifier .preferredSize(animate(if (female.value) 100.dp else 250.dp)) .border(width = animate(if (female.value) 0.dp else 4.dp), color = animate(if (female.value) Color.Transparent else Color.Red)) .padding(8.dp) .clickable { female.value = !female.value } .clip(RoundedCornerShape(animate(if (female.value) 0.dp else 8.dp))) ) Image( asset = imageResource(R.drawable.female), contentScale = ContentScale.Crop, modifier = Modifier // ... // Like previous image ) } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 val female = remember { mutableStateOf(true) } .clickable { female.value = !female.value } @Composable 1 fun GenderSelectAnimation() { 2 3 Row(horizontalArrangement = Arrangement.Center, 4 modifier = Modifier.padding(8.dp).fillMaxWidth(), 5 verticalAlignment = Alignment.CenterVertically 6 ) { 7 Image( 8 asset = imageResource(R.drawable.male), 9 contentScale = ContentScale.Crop, 10 modifier = Modifier 11 .preferredSize(animate(if (female.value) 100.dp else 250.dp)) 12 .border(width = animate(if (female.value) 0.dp else 4.dp), 13 color = animate(if (female.value) Color.Transparent else Color.Red)) 14 .padding(8.dp) 15 16 .clip(RoundedCornerShape(animate(if (female.value) 0.dp else 8.dp))) 17 ) 18 Image( 19 asset = imageResource(R.drawable.female), 20 contentScale = ContentScale.Crop, 21 modifier = Modifier 22 // ... 23 // Like previous image 24 ) 25 } 26 } 27 .preferredSize(animate(if (female.value) 100.dp else 250.dp)) .border(width = animate(if (female.value) 0.dp else 4.dp), color = animate(if (female.value) Color.Transparent else Color.Red)) .clip(RoundedCornerShape(animate(if (female.value) 0.dp else 8.dp))) @Composable 1 fun GenderSelectAnimation() { 2 val female = remember { mutableStateOf(true) } 3 Row(horizontalArrangement = Arrangement.Center, 4 modifier = Modifier.padding(8.dp).fillMaxWidth(), 5 verticalAlignment = Alignment.CenterVertically 6 ) { 7 Image( 8 asset = imageResource(R.drawable.male), 9 contentScale = ContentScale.Crop, 10 modifier = Modifier 11 12 13 14 .padding(8.dp) 15 .clickable { female.value = !female.value } 16 17 ) 18 Image( 19 asset = imageResource(R.drawable.female), 20 contentScale = ContentScale.Crop, 21 modifier = Modifier 22 // ... 23 // Like previous image 24 ) 25 } 26 } 27 The animate() 14

Slide 33

Slide 33 text

@Composable fun GenderSelectAnimation() { val female = remember { mutableStateOf(true) } Row(horizontalArrangement = Arrangement.Center, modifier = Modifier.padding(8.dp).fillMaxWidth(), verticalAlignment = Alignment.CenterVertically ) { Image( asset = imageResource(R.drawable.male), contentScale = ContentScale.Crop, modifier = Modifier .preferredSize(animate(if (female.value) 100.dp else 250.dp)) .border(width = animate(if (female.value) 0.dp else 4.dp), color = animate(if (female.value) Color.Transparent else Color.Red)) .padding(8.dp) .clickable { female.value = !female.value } .clip(RoundedCornerShape(animate(if (female.value) 0.dp else 8.dp))) ) Image( asset = imageResource(R.drawable.female), contentScale = ContentScale.Crop, modifier = Modifier // ... // Like previous image ) } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 val female = remember { mutableStateOf(true) } .clickable { female.value = !female.value } @Composable 1 fun GenderSelectAnimation() { 2 3 Row(horizontalArrangement = Arrangement.Center, 4 modifier = Modifier.padding(8.dp).fillMaxWidth(), 5 verticalAlignment = Alignment.CenterVertically 6 ) { 7 Image( 8 asset = imageResource(R.drawable.male), 9 contentScale = ContentScale.Crop, 10 modifier = Modifier 11 .preferredSize(animate(if (female.value) 100.dp else 250.dp)) 12 .border(width = animate(if (female.value) 0.dp else 4.dp), 13 color = animate(if (female.value) Color.Transparent else Color.Red)) 14 .padding(8.dp) 15 16 .clip(RoundedCornerShape(animate(if (female.value) 0.dp else 8.dp))) 17 ) 18 Image( 19 asset = imageResource(R.drawable.female), 20 contentScale = ContentScale.Crop, 21 modifier = Modifier 22 // ... 23 // Like previous image 24 ) 25 } 26 } 27 .preferredSize(animate(if (female.value) 100.dp else 250.dp)) .border(width = animate(if (female.value) 0.dp else 4.dp), color = animate(if (female.value) Color.Transparent else Color.Red)) .clip(RoundedCornerShape(animate(if (female.value) 0.dp else 8.dp))) @Composable 1 fun GenderSelectAnimation() { 2 val female = remember { mutableStateOf(true) } 3 Row(horizontalArrangement = Arrangement.Center, 4 modifier = Modifier.padding(8.dp).fillMaxWidth(), 5 verticalAlignment = Alignment.CenterVertically 6 ) { 7 Image( 8 asset = imageResource(R.drawable.male), 9 contentScale = ContentScale.Crop, 10 modifier = Modifier 11 12 13 14 .padding(8.dp) 15 .clickable { female.value = !female.value } 16 17 ) 18 Image( 19 asset = imageResource(R.drawable.female), 20 contentScale = ContentScale.Crop, 21 modifier = Modifier 22 // ... 23 // Like previous image 24 ) 25 } 26 } 27 @Composable fun GenderSelectAnimation() { val female = remember { mutableStateOf(true) } Row(horizontalArrangement = Arrangement.Center, modifier = Modifier.padding(8.dp).fillMaxWidth(), verticalAlignment = Alignment.CenterVertically ) { Image( asset = imageResource(R.drawable.male), contentScale = ContentScale.Crop, modifier = Modifier .preferredSize(animate(if (female.value) 100.dp else 250.dp)) .border(width = animate(if (female.value) 0.dp else 4.dp), color = animate(if (female.value) Color.Transparent else Color.Red)) .padding(8.dp) .clickable { female.value = !female.value } .clip(RoundedCornerShape(animate(if (female.value) 0.dp else 8.dp))) ) Image( asset = imageResource(R.drawable.female), contentScale = ContentScale.Crop, modifier = Modifier // ... // Like previous image ) } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 The animate() 14

Slide 34

Slide 34 text

Examples of animate() By Gurupreet Singh github.com/Gurupreet/ComposeCookBook 15

Slide 35

Slide 35 text

Animations in Jetpack Compose Repeated Animations with AnimatedValue The animateContentSize() Modifier The AnimatedVisibility Composable Single Value Animations with animate() Repeated Animations with AnimatedValue Utilizing transitions to make solid animations 16

Slide 36

Slide 36 text

@Composable fun HeartBeatDemo() { val animScale = animatedFloat(initVal = 1f) val animColor = animatedColor(initVal = Color.Red) onActive { animScale.animateTo( targetValue = 1.3f, anim = repeatable( iterations = AnimationConstants.Infinite, animation = tween(durationMillis = 300, easing = FastOutLinearInEasing, delayMillis = 1000) ) ) animColor.animateTo( targetValue = Color.Blue, anim = repeatable( iterations = AnimationConstants.Infinite, animation = tween(durationMillis = 300, easing = LinearEasing, delayMillis = 1000) ) ) } Image(asset = Icons.Default.Favorite, modifier = Modifier.padding(10.dp).size((40*animScale.value).dp), colorFilter = ColorFilter.tint(animColor.value) ) } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 Repeated Animations with AnimatedValue 17

Slide 37

Slide 37 text

@Composable fun HeartBeatDemo() { val animScale = animatedFloat(initVal = 1f) val animColor = animatedColor(initVal = Color.Red) onActive { animScale.animateTo( targetValue = 1.3f, anim = repeatable( iterations = AnimationConstants.Infinite, animation = tween(durationMillis = 300, easing = FastOutLinearInEasing, delayMillis = 1000) ) ) animColor.animateTo( targetValue = Color.Blue, anim = repeatable( iterations = AnimationConstants.Infinite, animation = tween(durationMillis = 300, easing = LinearEasing, delayMillis = 1000) ) ) } Image(asset = Icons.Default.Favorite, modifier = Modifier.padding(10.dp).size((40*animScale.value).dp), colorFilter = ColorFilter.tint(animColor.value) ) } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 val animScale = animatedFloat(initVal = 1f) val animColor = animatedColor(initVal = Color.Red) @Composable 1 fun HeartBeatDemo() { 2 3 4 5 onActive { 6 animScale.animateTo( 7 targetValue = 1.3f, 8 anim = repeatable( 9 iterations = AnimationConstants.Infinite, 10 animation = tween(durationMillis = 300, 11 easing = FastOutLinearInEasing, delayMillis = 1000) 12 ) 13 ) 14 15 animColor.animateTo( 16 targetValue = Color.Blue, 17 anim = repeatable( 18 iterations = AnimationConstants.Infinite, 19 animation = tween(durationMillis = 300, 20 easing = LinearEasing, delayMillis = 1000) 21 ) 22 ) 23 } 24 25 Image(asset = Icons.Default.Favorite, 26 modifier = Modifier.padding(10.dp).size((40*animScale.value).dp), 27 colorFilter = ColorFilter.tint(animColor.value) 28 ) 29 } 30 Repeated Animations with AnimatedValue 17

Slide 38

Slide 38 text

@Composable fun HeartBeatDemo() { val animScale = animatedFloat(initVal = 1f) val animColor = animatedColor(initVal = Color.Red) onActive { animScale.animateTo( targetValue = 1.3f, anim = repeatable( iterations = AnimationConstants.Infinite, animation = tween(durationMillis = 300, easing = FastOutLinearInEasing, delayMillis = 1000) ) ) animColor.animateTo( targetValue = Color.Blue, anim = repeatable( iterations = AnimationConstants.Infinite, animation = tween(durationMillis = 300, easing = LinearEasing, delayMillis = 1000) ) ) } Image(asset = Icons.Default.Favorite, modifier = Modifier.padding(10.dp).size((40*animScale.value).dp), colorFilter = ColorFilter.tint(animColor.value) ) } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 val animScale = animatedFloat(initVal = 1f) val animColor = animatedColor(initVal = Color.Red) @Composable 1 fun HeartBeatDemo() { 2 3 4 5 onActive { 6 animScale.animateTo( 7 targetValue = 1.3f, 8 anim = repeatable( 9 iterations = AnimationConstants.Infinite, 10 animation = tween(durationMillis = 300, 11 easing = FastOutLinearInEasing, delayMillis = 1000) 12 ) 13 ) 14 15 animColor.animateTo( 16 targetValue = Color.Blue, 17 anim = repeatable( 18 iterations = AnimationConstants.Infinite, 19 animation = tween(durationMillis = 300, 20 easing = LinearEasing, delayMillis = 1000) 21 ) 22 ) 23 } 24 25 Image(asset = Icons.Default.Favorite, 26 modifier = Modifier.padding(10.dp).size((40*animScale.value).dp), 27 colorFilter = ColorFilter.tint(animColor.value) 28 ) 29 } 30 animScale.animateTo( targetValue = 1.3f, anim = repeatable( iterations = AnimationConstants.Infinite, animation = tween(durationMillis = 300, easing = FastOutLinearInEasing, delayMillis = 1000) ) ) @Composable 1 fun HeartBeatDemo() { 2 val animScale = animatedFloat(initVal = 1f) 3 val animColor = animatedColor(initVal = Color.Red) 4 5 onActive { 6 7 8 9 10 11 12 13 14 15 animColor.animateTo( 16 targetValue = Color.Blue, 17 anim = repeatable( 18 iterations = AnimationConstants.Infinite, 19 animation = tween(durationMillis = 300, 20 easing = LinearEasing, delayMillis = 1000) 21 ) 22 ) 23 } 24 25 Image(asset = Icons.Default.Favorite, 26 modifier = Modifier.padding(10.dp).size((40*animScale.value).dp), 27 colorFilter = ColorFilter.tint(animColor.value) 28 ) 29 } 30 Repeated Animations with AnimatedValue 17

Slide 39

Slide 39 text

@Composable fun HeartBeatDemo() { val animScale = animatedFloat(initVal = 1f) val animColor = animatedColor(initVal = Color.Red) onActive { animScale.animateTo( targetValue = 1.3f, anim = repeatable( iterations = AnimationConstants.Infinite, animation = tween(durationMillis = 300, easing = FastOutLinearInEasing, delayMillis = 1000) ) ) animColor.animateTo( targetValue = Color.Blue, anim = repeatable( iterations = AnimationConstants.Infinite, animation = tween(durationMillis = 300, easing = LinearEasing, delayMillis = 1000) ) ) } Image(asset = Icons.Default.Favorite, modifier = Modifier.padding(10.dp).size((40*animScale.value).dp), colorFilter = ColorFilter.tint(animColor.value) ) } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 val animScale = animatedFloat(initVal = 1f) val animColor = animatedColor(initVal = Color.Red) @Composable 1 fun HeartBeatDemo() { 2 3 4 5 onActive { 6 animScale.animateTo( 7 targetValue = 1.3f, 8 anim = repeatable( 9 iterations = AnimationConstants.Infinite, 10 animation = tween(durationMillis = 300, 11 easing = FastOutLinearInEasing, delayMillis = 1000) 12 ) 13 ) 14 15 animColor.animateTo( 16 targetValue = Color.Blue, 17 anim = repeatable( 18 iterations = AnimationConstants.Infinite, 19 animation = tween(durationMillis = 300, 20 easing = LinearEasing, delayMillis = 1000) 21 ) 22 ) 23 } 24 25 Image(asset = Icons.Default.Favorite, 26 modifier = Modifier.padding(10.dp).size((40*animScale.value).dp), 27 colorFilter = ColorFilter.tint(animColor.value) 28 ) 29 } 30 animScale.animateTo( targetValue = 1.3f, anim = repeatable( iterations = AnimationConstants.Infinite, animation = tween(durationMillis = 300, easing = FastOutLinearInEasing, delayMillis = 1000) ) ) @Composable 1 fun HeartBeatDemo() { 2 val animScale = animatedFloat(initVal = 1f) 3 val animColor = animatedColor(initVal = Color.Red) 4 5 onActive { 6 7 8 9 10 11 12 13 14 15 animColor.animateTo( 16 targetValue = Color.Blue, 17 anim = repeatable( 18 iterations = AnimationConstants.Infinite, 19 animation = tween(durationMillis = 300, 20 easing = LinearEasing, delayMillis = 1000) 21 ) 22 ) 23 } 24 25 Image(asset = Icons.Default.Favorite, 26 modifier = Modifier.padding(10.dp).size((40*animScale.value).dp), 27 colorFilter = ColorFilter.tint(animColor.value) 28 ) 29 } 30 modifier = Modifier.padding(10.dp).size((40*animScale.value).dp), colorFilter = ColorFilter.tint(animColor.value) @Composable 1 fun HeartBeatDemo() { 2 val animScale = animatedFloat(initVal = 1f) 3 val animColor = animatedColor(initVal = Color.Red) 4 5 onActive { 6 animScale.animateTo( 7 targetValue = 1.3f, 8 anim = repeatable( 9 iterations = AnimationConstants.Infinite, 10 animation = tween(durationMillis = 300, 11 easing = FastOutLinearInEasing, delayMillis = 1000) 12 ) 13 ) 14 15 animColor.animateTo( 16 targetValue = Color.Blue, 17 anim = repeatable( 18 iterations = AnimationConstants.Infinite, 19 animation = tween(durationMillis = 300, 20 easing = LinearEasing, delayMillis = 1000) 21 ) 22 ) 23 } 24 25 Image(asset = Icons.Default.Favorite, 26 27 28 ) 29 } 30 Repeated Animations with AnimatedValue 17

Slide 40

Slide 40 text

@Composable fun HeartBeatDemo() { val animScale = animatedFloat(initVal = 1f) val animColor = animatedColor(initVal = Color.Red) onActive { animScale.animateTo( targetValue = 1.3f, anim = repeatable( iterations = AnimationConstants.Infinite, animation = tween(durationMillis = 300, easing = FastOutLinearInEasing, delayMillis = 1000) ) ) animColor.animateTo( targetValue = Color.Blue, anim = repeatable( iterations = AnimationConstants.Infinite, animation = tween(durationMillis = 300, easing = LinearEasing, delayMillis = 1000) ) ) } Image(asset = Icons.Default.Favorite, modifier = Modifier.padding(10.dp).size((40*animScale.value).dp), colorFilter = ColorFilter.tint(animColor.value) ) } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 val animScale = animatedFloat(initVal = 1f) val animColor = animatedColor(initVal = Color.Red) @Composable 1 fun HeartBeatDemo() { 2 3 4 5 onActive { 6 animScale.animateTo( 7 targetValue = 1.3f, 8 anim = repeatable( 9 iterations = AnimationConstants.Infinite, 10 animation = tween(durationMillis = 300, 11 easing = FastOutLinearInEasing, delayMillis = 1000) 12 ) 13 ) 14 15 animColor.animateTo( 16 targetValue = Color.Blue, 17 anim = repeatable( 18 iterations = AnimationConstants.Infinite, 19 animation = tween(durationMillis = 300, 20 easing = LinearEasing, delayMillis = 1000) 21 ) 22 ) 23 } 24 25 Image(asset = Icons.Default.Favorite, 26 modifier = Modifier.padding(10.dp).size((40*animScale.value).dp), 27 colorFilter = ColorFilter.tint(animColor.value) 28 ) 29 } 30 animScale.animateTo( targetValue = 1.3f, anim = repeatable( iterations = AnimationConstants.Infinite, animation = tween(durationMillis = 300, easing = FastOutLinearInEasing, delayMillis = 1000) ) ) @Composable 1 fun HeartBeatDemo() { 2 val animScale = animatedFloat(initVal = 1f) 3 val animColor = animatedColor(initVal = Color.Red) 4 5 onActive { 6 7 8 9 10 11 12 13 14 15 animColor.animateTo( 16 targetValue = Color.Blue, 17 anim = repeatable( 18 iterations = AnimationConstants.Infinite, 19 animation = tween(durationMillis = 300, 20 easing = LinearEasing, delayMillis = 1000) 21 ) 22 ) 23 } 24 25 Image(asset = Icons.Default.Favorite, 26 modifier = Modifier.padding(10.dp).size((40*animScale.value).dp), 27 colorFilter = ColorFilter.tint(animColor.value) 28 ) 29 } 30 modifier = Modifier.padding(10.dp).size((40*animScale.value).dp), colorFilter = ColorFilter.tint(animColor.value) @Composable 1 fun HeartBeatDemo() { 2 val animScale = animatedFloat(initVal = 1f) 3 val animColor = animatedColor(initVal = Color.Red) 4 5 onActive { 6 animScale.animateTo( 7 targetValue = 1.3f, 8 anim = repeatable( 9 iterations = AnimationConstants.Infinite, 10 animation = tween(durationMillis = 300, 11 easing = FastOutLinearInEasing, delayMillis = 1000) 12 ) 13 ) 14 15 animColor.animateTo( 16 targetValue = Color.Blue, 17 anim = repeatable( 18 iterations = AnimationConstants.Infinite, 19 animation = tween(durationMillis = 300, 20 easing = LinearEasing, delayMillis = 1000) 21 ) 22 ) 23 } 24 25 Image(asset = Icons.Default.Favorite, 26 27 28 ) 29 } 30 @Composable fun HeartBeatDemo() { val animScale = animatedFloat(initVal = 1f) val animColor = animatedColor(initVal = Color.Red) onActive { animScale.animateTo( targetValue = 1.3f, anim = repeatable( iterations = AnimationConstants.Infinite, animation = tween(durationMillis = 300, easing = FastOutLinearInEasing, delayMillis = 1000) ) ) animColor.animateTo( targetValue = Color.Blue, anim = repeatable( iterations = AnimationConstants.Infinite, animation = tween(durationMillis = 300, easing = LinearEasing, delayMillis = 1000) ) ) } Image(asset = Icons.Default.Favorite, modifier = Modifier.padding(10.dp).size((40*animScale.value).dp), colorFilter = ColorFilter.tint(animColor.value) ) } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 Repeated Animations with AnimatedValue 17

Slide 41

Slide 41 text

Compose Canvas 101 A simple Spacer() to allow you to draw anything on it @Composable fun Canvas ( modifier: Modifier, onDraw: DrawScope.() -> Unit ) = Spacer(modifier.drawBehind(onDraw)) 1 2 3 4 5 6 18

Slide 42

Slide 42 text

Compose Canvas 101 A simple Spacer() to allow you to draw anything on it @Composable fun Canvas ( modifier: Modifier, onDraw: DrawScope.() -> Unit ) = Spacer(modifier.drawBehind(onDraw)) 1 2 3 4 5 6 ) = Spacer(modifier.drawBehind(onDraw)) @Composable 1 fun Canvas 2 ( 3 modifier: Modifier, 4 onDraw: DrawScope.() -> Unit 5 6 18

Slide 43

Slide 43 text

Compose Canvas 101 A simple Spacer() to allow you to draw anything on it @Composable fun Canvas ( modifier: Modifier, onDraw: DrawScope.() -> Unit ) = Spacer(modifier.drawBehind(onDraw)) 1 2 3 4 5 6 ) = Spacer(modifier.drawBehind(onDraw)) @Composable 1 fun Canvas 2 ( 3 modifier: Modifier, 4 onDraw: DrawScope.() -> Unit 5 6 modifier: Modifier, @Composable 1 fun Canvas 2 ( 3 4 onDraw: DrawScope.() -> Unit 5 ) = Spacer(modifier.drawBehind(onDraw)) 6 18

Slide 44

Slide 44 text

Compose Canvas 101 A simple Spacer() to allow you to draw anything on it @Composable fun Canvas ( modifier: Modifier, onDraw: DrawScope.() -> Unit ) = Spacer(modifier.drawBehind(onDraw)) 1 2 3 4 5 6 ) = Spacer(modifier.drawBehind(onDraw)) @Composable 1 fun Canvas 2 ( 3 modifier: Modifier, 4 onDraw: DrawScope.() -> Unit 5 6 modifier: Modifier, @Composable 1 fun Canvas 2 ( 3 4 onDraw: DrawScope.() -> Unit 5 ) = Spacer(modifier.drawBehind(onDraw)) 6 onDraw: DrawScope.() -> Unit @Composable 1 fun Canvas 2 ( 3 modifier: Modifier, 4 5 ) = Spacer(modifier.drawBehind(onDraw)) 6 18

Slide 45

Slide 45 text

Compose Canvas 101 A simple Spacer() to allow you to draw anything on it @Composable fun Canvas ( modifier: Modifier, onDraw: DrawScope.() -> Unit ) = Spacer(modifier.drawBehind(onDraw)) 1 2 3 4 5 6 ) = Spacer(modifier.drawBehind(onDraw)) @Composable 1 fun Canvas 2 ( 3 modifier: Modifier, 4 onDraw: DrawScope.() -> Unit 5 6 modifier: Modifier, @Composable 1 fun Canvas 2 ( 3 4 onDraw: DrawScope.() -> Unit 5 ) = Spacer(modifier.drawBehind(onDraw)) 6 onDraw: DrawScope.() -> Unit @Composable 1 fun Canvas 2 ( 3 modifier: Modifier, 4 5 ) = Spacer(modifier.drawBehind(onDraw)) 6 @Composable fun Canvas ( modifier: Modifier, onDraw: DrawScope.() -> Unit ) = Spacer(modifier.drawBehind(onDraw)) 1 2 3 4 5 6 18

Slide 46

Slide 46 text

Compose Canvas 101 DrawScope - Handles the drawing API drawRect() drawOval() drawLine() drawImage() drawRoundRect() drawCircle() drawArc() drawPath() fun DrawScope.drawMyShape() { } 19

Slide 47

Slide 47 text

Compose Canvas 101 Custom View Example in Canvas Canvas(modifier = Modifier.fillMaxSize()) { drawCircle( color = Color.Red, radius = 300f ) drawCircle( color = Color.Green, radius = 200f ) drawCircle( color = Color.Blue, radius = 100f ) } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 20

Slide 48

Slide 48 text

Compose Canvas 101 Custom View Example in Canvas Canvas(modifier = Modifier.fillMaxSize()) { drawCircle( color = Color.Red, radius = 300f ) drawCircle( color = Color.Green, radius = 200f ) drawCircle( color = Color.Blue, radius = 100f ) } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 Canvas(modifier = Modifier.fillMaxSize()) { 1 drawCircle( 2 color = Color.Red, 3 radius = 300f 4 ) 5 6 drawCircle( 7 color = Color.Green, 8 radius = 200f 9 ) 10 11 drawCircle( 12 color = Color.Blue, 13 radius = 100f 14 ) 15 } 16 20

Slide 49

Slide 49 text

Compose Canvas 101 Custom View Example in Canvas Canvas(modifier = Modifier.fillMaxSize()) { drawCircle( color = Color.Red, radius = 300f ) drawCircle( color = Color.Green, radius = 200f ) drawCircle( color = Color.Blue, radius = 100f ) } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 Canvas(modifier = Modifier.fillMaxSize()) { 1 drawCircle( 2 color = Color.Red, 3 radius = 300f 4 ) 5 6 drawCircle( 7 color = Color.Green, 8 radius = 200f 9 ) 10 11 drawCircle( 12 color = Color.Blue, 13 radius = 100f 14 ) 15 } 16 drawCircle( color = Color.Red, radius = 300f ) Canvas(modifier = Modifier.fillMaxSize()) { 1 2 3 4 5 6 drawCircle( 7 color = Color.Green, 8 radius = 200f 9 ) 10 11 drawCircle( 12 color = Color.Blue, 13 radius = 100f 14 ) 15 } 16 20

Slide 50

Slide 50 text

Compose Canvas 101 Custom View Example in Canvas Canvas(modifier = Modifier.fillMaxSize()) { drawCircle( color = Color.Red, radius = 300f ) drawCircle( color = Color.Green, radius = 200f ) drawCircle( color = Color.Blue, radius = 100f ) } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 Canvas(modifier = Modifier.fillMaxSize()) { 1 drawCircle( 2 color = Color.Red, 3 radius = 300f 4 ) 5 6 drawCircle( 7 color = Color.Green, 8 radius = 200f 9 ) 10 11 drawCircle( 12 color = Color.Blue, 13 radius = 100f 14 ) 15 } 16 drawCircle( color = Color.Red, radius = 300f ) Canvas(modifier = Modifier.fillMaxSize()) { 1 2 3 4 5 6 drawCircle( 7 color = Color.Green, 8 radius = 200f 9 ) 10 11 drawCircle( 12 color = Color.Blue, 13 radius = 100f 14 ) 15 } 16 drawCircle( color = Color.Green, radius = 200f ) Canvas(modifier = Modifier.fillMaxSize()) { 1 drawCircle( 2 color = Color.Red, 3 radius = 300f 4 ) 5 6 7 8 9 10 11 drawCircle( 12 color = Color.Blue, 13 radius = 100f 14 ) 15 } 16 20

Slide 51

Slide 51 text

Compose Canvas 101 Custom View Example in Canvas Canvas(modifier = Modifier.fillMaxSize()) { drawCircle( color = Color.Red, radius = 300f ) drawCircle( color = Color.Green, radius = 200f ) drawCircle( color = Color.Blue, radius = 100f ) } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 Canvas(modifier = Modifier.fillMaxSize()) { 1 drawCircle( 2 color = Color.Red, 3 radius = 300f 4 ) 5 6 drawCircle( 7 color = Color.Green, 8 radius = 200f 9 ) 10 11 drawCircle( 12 color = Color.Blue, 13 radius = 100f 14 ) 15 } 16 drawCircle( color = Color.Red, radius = 300f ) Canvas(modifier = Modifier.fillMaxSize()) { 1 2 3 4 5 6 drawCircle( 7 color = Color.Green, 8 radius = 200f 9 ) 10 11 drawCircle( 12 color = Color.Blue, 13 radius = 100f 14 ) 15 } 16 drawCircle( color = Color.Green, radius = 200f ) Canvas(modifier = Modifier.fillMaxSize()) { 1 drawCircle( 2 color = Color.Red, 3 radius = 300f 4 ) 5 6 7 8 9 10 11 drawCircle( 12 color = Color.Blue, 13 radius = 100f 14 ) 15 } 16 Canvas(modifier = Modifier.fillMaxSize()) { drawCircle( color = Color.Red, radius = 300f ) drawCircle( color = Color.Green, radius = 200f ) drawCircle( color = Color.Blue, radius = 100f ) } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 20

Slide 52

Slide 52 text

AnimatedValue on Canvas @Composable fun MovingSquare() { val animPosX = animatedFloat(initVal = 0f) onActive { animPosX.animateTo( targetValue = 500f, anim = repeatable( iterations = AnimationConstants.Infinite, animation = tween(durationMillis = 1000) ) ) } Canvas(modifier = Modifier.preferredSize(100.dp), onDraw = { withTransform({ translate(left = animPosX.value) }) { drawRect(color = Color.Red) } }) } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 A simple moving square example 21

Slide 53

Slide 53 text

AnimatedValue on Canvas @Composable fun MovingSquare() { val animPosX = animatedFloat(initVal = 0f) onActive { animPosX.animateTo( targetValue = 500f, anim = repeatable( iterations = AnimationConstants.Infinite, animation = tween(durationMillis = 1000) ) ) } Canvas(modifier = Modifier.preferredSize(100.dp), onDraw = { withTransform({ translate(left = animPosX.value) }) { drawRect(color = Color.Red) } }) } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 val animPosX = animatedFloat(initVal = 0f) @Composable 1 fun MovingSquare() { 2 3 onActive { 4 animPosX.animateTo( 5 targetValue = 500f, 6 anim = repeatable( 7 iterations = AnimationConstants.Infinite, 8 animation = tween(durationMillis = 1000) 9 ) 10 ) 11 } 12 13 Canvas(modifier = Modifier.preferredSize(100.dp), onDraw = { 14 withTransform({ 15 translate(left = animPosX.value) 16 }) { 17 drawRect(color = Color.Red) 18 } 19 }) 20 } 21 A simple moving square example 21

Slide 54

Slide 54 text

AnimatedValue on Canvas @Composable fun MovingSquare() { val animPosX = animatedFloat(initVal = 0f) onActive { animPosX.animateTo( targetValue = 500f, anim = repeatable( iterations = AnimationConstants.Infinite, animation = tween(durationMillis = 1000) ) ) } Canvas(modifier = Modifier.preferredSize(100.dp), onDraw = { withTransform({ translate(left = animPosX.value) }) { drawRect(color = Color.Red) } }) } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 val animPosX = animatedFloat(initVal = 0f) @Composable 1 fun MovingSquare() { 2 3 onActive { 4 animPosX.animateTo( 5 targetValue = 500f, 6 anim = repeatable( 7 iterations = AnimationConstants.Infinite, 8 animation = tween(durationMillis = 1000) 9 ) 10 ) 11 } 12 13 Canvas(modifier = Modifier.preferredSize(100.dp), onDraw = { 14 withTransform({ 15 translate(left = animPosX.value) 16 }) { 17 drawRect(color = Color.Red) 18 } 19 }) 20 } 21 animPosX.animateTo( targetValue = 500f, anim = repeatable( iterations = AnimationConstants.Infinite, animation = tween(durationMillis = 1000) ) ) @Composable 1 fun MovingSquare() { 2 val animPosX = animatedFloat(initVal = 0f) 3 onActive { 4 5 6 7 8 9 10 11 } 12 13 Canvas(modifier = Modifier.preferredSize(100.dp), onDraw = { 14 withTransform({ 15 translate(left = animPosX.value) 16 }) { 17 drawRect(color = Color.Red) 18 } 19 }) 20 } 21 A simple moving square example 21

Slide 55

Slide 55 text

AnimatedValue on Canvas @Composable fun MovingSquare() { val animPosX = animatedFloat(initVal = 0f) onActive { animPosX.animateTo( targetValue = 500f, anim = repeatable( iterations = AnimationConstants.Infinite, animation = tween(durationMillis = 1000) ) ) } Canvas(modifier = Modifier.preferredSize(100.dp), onDraw = { withTransform({ translate(left = animPosX.value) }) { drawRect(color = Color.Red) } }) } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 val animPosX = animatedFloat(initVal = 0f) @Composable 1 fun MovingSquare() { 2 3 onActive { 4 animPosX.animateTo( 5 targetValue = 500f, 6 anim = repeatable( 7 iterations = AnimationConstants.Infinite, 8 animation = tween(durationMillis = 1000) 9 ) 10 ) 11 } 12 13 Canvas(modifier = Modifier.preferredSize(100.dp), onDraw = { 14 withTransform({ 15 translate(left = animPosX.value) 16 }) { 17 drawRect(color = Color.Red) 18 } 19 }) 20 } 21 animPosX.animateTo( targetValue = 500f, anim = repeatable( iterations = AnimationConstants.Infinite, animation = tween(durationMillis = 1000) ) ) @Composable 1 fun MovingSquare() { 2 val animPosX = animatedFloat(initVal = 0f) 3 onActive { 4 5 6 7 8 9 10 11 } 12 13 Canvas(modifier = Modifier.preferredSize(100.dp), onDraw = { 14 withTransform({ 15 translate(left = animPosX.value) 16 }) { 17 drawRect(color = Color.Red) 18 } 19 }) 20 } 21 Canvas(modifier = Modifier.preferredSize(100.dp), onDraw = { @Composable 1 fun MovingSquare() { 2 val animPosX = animatedFloat(initVal = 0f) 3 onActive { 4 animPosX.animateTo( 5 targetValue = 500f, 6 anim = repeatable( 7 iterations = AnimationConstants.Infinite, 8 animation = tween(durationMillis = 1000) 9 ) 10 ) 11 } 12 13 14 withTransform({ 15 translate(left = animPosX.value) 16 }) { 17 drawRect(color = Color.Red) 18 } 19 }) 20 } 21 A simple moving square example 21

Slide 56

Slide 56 text

AnimatedValue on Canvas @Composable fun MovingSquare() { val animPosX = animatedFloat(initVal = 0f) onActive { animPosX.animateTo( targetValue = 500f, anim = repeatable( iterations = AnimationConstants.Infinite, animation = tween(durationMillis = 1000) ) ) } Canvas(modifier = Modifier.preferredSize(100.dp), onDraw = { withTransform({ translate(left = animPosX.value) }) { drawRect(color = Color.Red) } }) } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 val animPosX = animatedFloat(initVal = 0f) @Composable 1 fun MovingSquare() { 2 3 onActive { 4 animPosX.animateTo( 5 targetValue = 500f, 6 anim = repeatable( 7 iterations = AnimationConstants.Infinite, 8 animation = tween(durationMillis = 1000) 9 ) 10 ) 11 } 12 13 Canvas(modifier = Modifier.preferredSize(100.dp), onDraw = { 14 withTransform({ 15 translate(left = animPosX.value) 16 }) { 17 drawRect(color = Color.Red) 18 } 19 }) 20 } 21 animPosX.animateTo( targetValue = 500f, anim = repeatable( iterations = AnimationConstants.Infinite, animation = tween(durationMillis = 1000) ) ) @Composable 1 fun MovingSquare() { 2 val animPosX = animatedFloat(initVal = 0f) 3 onActive { 4 5 6 7 8 9 10 11 } 12 13 Canvas(modifier = Modifier.preferredSize(100.dp), onDraw = { 14 withTransform({ 15 translate(left = animPosX.value) 16 }) { 17 drawRect(color = Color.Red) 18 } 19 }) 20 } 21 Canvas(modifier = Modifier.preferredSize(100.dp), onDraw = { @Composable 1 fun MovingSquare() { 2 val animPosX = animatedFloat(initVal = 0f) 3 onActive { 4 animPosX.animateTo( 5 targetValue = 500f, 6 anim = repeatable( 7 iterations = AnimationConstants.Infinite, 8 animation = tween(durationMillis = 1000) 9 ) 10 ) 11 } 12 13 14 withTransform({ 15 translate(left = animPosX.value) 16 }) { 17 drawRect(color = Color.Red) 18 } 19 }) 20 } 21 drawRect(color = Color.Red) @Composable 1 fun MovingSquare() { 2 val animPosX = animatedFloat(initVal = 0f) 3 onActive { 4 animPosX.animateTo( 5 targetValue = 500f, 6 anim = repeatable( 7 iterations = AnimationConstants.Infinite, 8 animation = tween(durationMillis = 1000) 9 ) 10 ) 11 } 12 13 Canvas(modifier = Modifier.preferredSize(100.dp), onDraw = { 14 withTransform({ 15 translate(left = animPosX.value) 16 }) { 17 18 } 19 }) 20 } 21 A simple moving square example 21

Slide 57

Slide 57 text

AnimatedValue on Canvas @Composable fun MovingSquare() { val animPosX = animatedFloat(initVal = 0f) onActive { animPosX.animateTo( targetValue = 500f, anim = repeatable( iterations = AnimationConstants.Infinite, animation = tween(durationMillis = 1000) ) ) } Canvas(modifier = Modifier.preferredSize(100.dp), onDraw = { withTransform({ translate(left = animPosX.value) }) { drawRect(color = Color.Red) } }) } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 val animPosX = animatedFloat(initVal = 0f) @Composable 1 fun MovingSquare() { 2 3 onActive { 4 animPosX.animateTo( 5 targetValue = 500f, 6 anim = repeatable( 7 iterations = AnimationConstants.Infinite, 8 animation = tween(durationMillis = 1000) 9 ) 10 ) 11 } 12 13 Canvas(modifier = Modifier.preferredSize(100.dp), onDraw = { 14 withTransform({ 15 translate(left = animPosX.value) 16 }) { 17 drawRect(color = Color.Red) 18 } 19 }) 20 } 21 animPosX.animateTo( targetValue = 500f, anim = repeatable( iterations = AnimationConstants.Infinite, animation = tween(durationMillis = 1000) ) ) @Composable 1 fun MovingSquare() { 2 val animPosX = animatedFloat(initVal = 0f) 3 onActive { 4 5 6 7 8 9 10 11 } 12 13 Canvas(modifier = Modifier.preferredSize(100.dp), onDraw = { 14 withTransform({ 15 translate(left = animPosX.value) 16 }) { 17 drawRect(color = Color.Red) 18 } 19 }) 20 } 21 Canvas(modifier = Modifier.preferredSize(100.dp), onDraw = { @Composable 1 fun MovingSquare() { 2 val animPosX = animatedFloat(initVal = 0f) 3 onActive { 4 animPosX.animateTo( 5 targetValue = 500f, 6 anim = repeatable( 7 iterations = AnimationConstants.Infinite, 8 animation = tween(durationMillis = 1000) 9 ) 10 ) 11 } 12 13 14 withTransform({ 15 translate(left = animPosX.value) 16 }) { 17 drawRect(color = Color.Red) 18 } 19 }) 20 } 21 drawRect(color = Color.Red) @Composable 1 fun MovingSquare() { 2 val animPosX = animatedFloat(initVal = 0f) 3 onActive { 4 animPosX.animateTo( 5 targetValue = 500f, 6 anim = repeatable( 7 iterations = AnimationConstants.Infinite, 8 animation = tween(durationMillis = 1000) 9 ) 10 ) 11 } 12 13 Canvas(modifier = Modifier.preferredSize(100.dp), onDraw = { 14 withTransform({ 15 translate(left = animPosX.value) 16 }) { 17 18 } 19 }) 20 } 21 withTransform({ translate(left = animPosX.value) @Composable 1 fun MovingSquare() { 2 val animPosX = animatedFloat(initVal = 0f) 3 onActive { 4 animPosX.animateTo( 5 targetValue = 500f, 6 anim = repeatable( 7 iterations = AnimationConstants.Infinite, 8 animation = tween(durationMillis = 1000) 9 ) 10 ) 11 } 12 13 Canvas(modifier = Modifier.preferredSize(100.dp), onDraw = { 14 15 16 }) { 17 drawRect(color = Color.Red) 18 } 19 }) 20 } 21 A simple moving square example 21

Slide 58

Slide 58 text

AnimatedValue on Canvas @Composable fun MovingSquare() { val animPosX = animatedFloat(initVal = 0f) onActive { animPosX.animateTo( targetValue = 500f, anim = repeatable( iterations = AnimationConstants.Infinite, animation = tween(durationMillis = 1000) ) ) } Canvas(modifier = Modifier.preferredSize(100.dp), onDraw = { withTransform({ translate(left = animPosX.value) }) { drawRect(color = Color.Red) } }) } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 val animPosX = animatedFloat(initVal = 0f) @Composable 1 fun MovingSquare() { 2 3 onActive { 4 animPosX.animateTo( 5 targetValue = 500f, 6 anim = repeatable( 7 iterations = AnimationConstants.Infinite, 8 animation = tween(durationMillis = 1000) 9 ) 10 ) 11 } 12 13 Canvas(modifier = Modifier.preferredSize(100.dp), onDraw = { 14 withTransform({ 15 translate(left = animPosX.value) 16 }) { 17 drawRect(color = Color.Red) 18 } 19 }) 20 } 21 animPosX.animateTo( targetValue = 500f, anim = repeatable( iterations = AnimationConstants.Infinite, animation = tween(durationMillis = 1000) ) ) @Composable 1 fun MovingSquare() { 2 val animPosX = animatedFloat(initVal = 0f) 3 onActive { 4 5 6 7 8 9 10 11 } 12 13 Canvas(modifier = Modifier.preferredSize(100.dp), onDraw = { 14 withTransform({ 15 translate(left = animPosX.value) 16 }) { 17 drawRect(color = Color.Red) 18 } 19 }) 20 } 21 Canvas(modifier = Modifier.preferredSize(100.dp), onDraw = { @Composable 1 fun MovingSquare() { 2 val animPosX = animatedFloat(initVal = 0f) 3 onActive { 4 animPosX.animateTo( 5 targetValue = 500f, 6 anim = repeatable( 7 iterations = AnimationConstants.Infinite, 8 animation = tween(durationMillis = 1000) 9 ) 10 ) 11 } 12 13 14 withTransform({ 15 translate(left = animPosX.value) 16 }) { 17 drawRect(color = Color.Red) 18 } 19 }) 20 } 21 drawRect(color = Color.Red) @Composable 1 fun MovingSquare() { 2 val animPosX = animatedFloat(initVal = 0f) 3 onActive { 4 animPosX.animateTo( 5 targetValue = 500f, 6 anim = repeatable( 7 iterations = AnimationConstants.Infinite, 8 animation = tween(durationMillis = 1000) 9 ) 10 ) 11 } 12 13 Canvas(modifier = Modifier.preferredSize(100.dp), onDraw = { 14 withTransform({ 15 translate(left = animPosX.value) 16 }) { 17 18 } 19 }) 20 } 21 withTransform({ translate(left = animPosX.value) @Composable 1 fun MovingSquare() { 2 val animPosX = animatedFloat(initVal = 0f) 3 onActive { 4 animPosX.animateTo( 5 targetValue = 500f, 6 anim = repeatable( 7 iterations = AnimationConstants.Infinite, 8 animation = tween(durationMillis = 1000) 9 ) 10 ) 11 } 12 13 Canvas(modifier = Modifier.preferredSize(100.dp), onDraw = { 14 15 16 }) { 17 drawRect(color = Color.Red) 18 } 19 }) 20 } 21 @Composable fun MovingSquare() { val animPosX = animatedFloat(initVal = 0f) onActive { animPosX.animateTo( targetValue = 500f, anim = repeatable( iterations = AnimationConstants.Infinite, animation = tween(durationMillis = 1000) ) ) } Canvas(modifier = Modifier.preferredSize(100.dp), onDraw = { withTransform({ translate(left = animPosX.value) }) { drawRect(color = Color.Red) } }) } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 A simple moving square example 21

Slide 59

Slide 59 text

More Canvas Examples Its all about mathematics & drawing By Alex Lockwood github.com/alexjlockwood/bees-and-bombs-compose/ github.com/wajahatkarim3/DinoCompose 22

Slide 60

Slide 60 text

Animations in Jetpack Compose Utilizing transitions to make solid animations The animateContentSize() Modifier The AnimatedVisibility Composable Single Value Animations with animate() Repeated Animations with AnimatedValue Utilizing transitions to make solid animations 23

Slide 61

Slide 61 text

Transitions - 1 class DroidconActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContent { DroidconEMEA2020Theme { Scaffold( topBar = { TopAppBar( /* App Bar */ ) }, floatingActionButton = { ExplodingFabButton() }, bodyContent = { // Content Composables } } } } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 24

Slide 62

Slide 62 text

Transitions - 1 class DroidconActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContent { DroidconEMEA2020Theme { Scaffold( topBar = { TopAppBar( /* App Bar */ ) }, floatingActionButton = { ExplodingFabButton() }, bodyContent = { // Content Composables } } } } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 Scaffold( class DroidconActivity : AppCompatActivity() { 1 override fun onCreate(savedInstanceState: Bundle?) { 2 super.onCreate(savedInstanceState) 3 setContent { 4 DroidconEMEA2020Theme { 5 6 topBar = { 7 TopAppBar( /* App Bar */ ) 8 }, 9 floatingActionButton = { 10 ExplodingFabButton() 11 }, 12 bodyContent = { 13 // Content Composables 14 } 15 } 16 } 17 } 18 } 19 24

Slide 63

Slide 63 text

Transitions - 1 class DroidconActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContent { DroidconEMEA2020Theme { Scaffold( topBar = { TopAppBar( /* App Bar */ ) }, floatingActionButton = { ExplodingFabButton() }, bodyContent = { // Content Composables } } } } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 Scaffold( class DroidconActivity : AppCompatActivity() { 1 override fun onCreate(savedInstanceState: Bundle?) { 2 super.onCreate(savedInstanceState) 3 setContent { 4 DroidconEMEA2020Theme { 5 6 topBar = { 7 TopAppBar( /* App Bar */ ) 8 }, 9 floatingActionButton = { 10 ExplodingFabButton() 11 }, 12 bodyContent = { 13 // Content Composables 14 } 15 } 16 } 17 } 18 } 19 floatingActionButton = { class DroidconActivity : AppCompatActivity() { 1 override fun onCreate(savedInstanceState: Bundle?) { 2 super.onCreate(savedInstanceState) 3 setContent { 4 DroidconEMEA2020Theme { 5 Scaffold( 6 topBar = { 7 TopAppBar( /* App Bar */ ) 8 }, 9 10 ExplodingFabButton() 11 }, 12 bodyContent = { 13 // Content Composables 14 } 15 } 16 } 17 } 18 } 19 24

Slide 64

Slide 64 text

Transitions - 1 class DroidconActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContent { DroidconEMEA2020Theme { Scaffold( topBar = { TopAppBar( /* App Bar */ ) }, floatingActionButton = { ExplodingFabButton() }, bodyContent = { // Content Composables } } } } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 Scaffold( class DroidconActivity : AppCompatActivity() { 1 override fun onCreate(savedInstanceState: Bundle?) { 2 super.onCreate(savedInstanceState) 3 setContent { 4 DroidconEMEA2020Theme { 5 6 topBar = { 7 TopAppBar( /* App Bar */ ) 8 }, 9 floatingActionButton = { 10 ExplodingFabButton() 11 }, 12 bodyContent = { 13 // Content Composables 14 } 15 } 16 } 17 } 18 } 19 floatingActionButton = { class DroidconActivity : AppCompatActivity() { 1 override fun onCreate(savedInstanceState: Bundle?) { 2 super.onCreate(savedInstanceState) 3 setContent { 4 DroidconEMEA2020Theme { 5 Scaffold( 6 topBar = { 7 TopAppBar( /* App Bar */ ) 8 }, 9 10 ExplodingFabButton() 11 }, 12 bodyContent = { 13 // Content Composables 14 } 15 } 16 } 17 } 18 } 19 ExplodingFabButton() class DroidconActivity : AppCompatActivity() { 1 override fun onCreate(savedInstanceState: Bundle?) { 2 super.onCreate(savedInstanceState) 3 setContent { 4 DroidconEMEA2020Theme { 5 Scaffold( 6 topBar = { 7 TopAppBar( /* App Bar */ ) 8 }, 9 floatingActionButton = { 10 11 }, 12 bodyContent = { 13 // Content Composables 14 } 15 } 16 } 17 } 18 } 19 24

Slide 65

Slide 65 text

Transitions - 1 class DroidconActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContent { DroidconEMEA2020Theme { Scaffold( topBar = { TopAppBar( /* App Bar */ ) }, floatingActionButton = { ExplodingFabButton() }, bodyContent = { // Content Composables } } } } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 Scaffold( class DroidconActivity : AppCompatActivity() { 1 override fun onCreate(savedInstanceState: Bundle?) { 2 super.onCreate(savedInstanceState) 3 setContent { 4 DroidconEMEA2020Theme { 5 6 topBar = { 7 TopAppBar( /* App Bar */ ) 8 }, 9 floatingActionButton = { 10 ExplodingFabButton() 11 }, 12 bodyContent = { 13 // Content Composables 14 } 15 } 16 } 17 } 18 } 19 floatingActionButton = { class DroidconActivity : AppCompatActivity() { 1 override fun onCreate(savedInstanceState: Bundle?) { 2 super.onCreate(savedInstanceState) 3 setContent { 4 DroidconEMEA2020Theme { 5 Scaffold( 6 topBar = { 7 TopAppBar( /* App Bar */ ) 8 }, 9 10 ExplodingFabButton() 11 }, 12 bodyContent = { 13 // Content Composables 14 } 15 } 16 } 17 } 18 } 19 ExplodingFabButton() class DroidconActivity : AppCompatActivity() { 1 override fun onCreate(savedInstanceState: Bundle?) { 2 super.onCreate(savedInstanceState) 3 setContent { 4 DroidconEMEA2020Theme { 5 Scaffold( 6 topBar = { 7 TopAppBar( /* App Bar */ ) 8 }, 9 floatingActionButton = { 10 11 }, 12 bodyContent = { 13 // Content Composables 14 } 15 } 16 } 17 } 18 } 19 class DroidconActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContent { DroidconEMEA2020Theme { Scaffold( topBar = { TopAppBar( /* App Bar */ ) }, floatingActionButton = { ExplodingFabButton() }, bodyContent = { // Content Composables } } } } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 24

Slide 66

Slide 66 text

Transitions - 2 enum class FabSizeState { NORMAL, EXPLODED } val fabSizeKey = FloatPropKey() @Composable fun ExplodingFabButton() { val fabSizeState = remember { mutableStateOf(FabSizeState.NORMAL) } val fabTransitionDef = transitionDefinition { // What happens when Normal state(FabSizeState.NORMAL) { this[fabSizeKey] = 80f } // What happens when Exploded state(FabSizeState.EXPLODED) { this[fabSizeKey] = 5000f } } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 25

Slide 67

Slide 67 text

Transitions - 2 enum class FabSizeState { NORMAL, EXPLODED } val fabSizeKey = FloatPropKey() @Composable fun ExplodingFabButton() { val fabSizeState = remember { mutableStateOf(FabSizeState.NORMAL) } val fabTransitionDef = transitionDefinition { // What happens when Normal state(FabSizeState.NORMAL) { this[fabSizeKey] = 80f } // What happens when Exploded state(FabSizeState.EXPLODED) { this[fabSizeKey] = 5000f } } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 @Composable fun ExplodingFabButton() { } enum class FabSizeState { 1 NORMAL, EXPLODED 2 } 3 4 val fabSizeKey = FloatPropKey() 5 6 7 8 val fabSizeState = remember { mutableStateOf(FabSizeState.NORMAL) } 9 10 val fabTransitionDef = transitionDefinition { 11 // What happens when Normal 12 state(FabSizeState.NORMAL) { 13 this[fabSizeKey] = 80f 14 } 15 16 // What happens when Exploded 17 state(FabSizeState.EXPLODED) { 18 this[fabSizeKey] = 5000f 19 } 20 } 21 22 25

Slide 68

Slide 68 text

Transitions - 2 enum class FabSizeState { NORMAL, EXPLODED } val fabSizeKey = FloatPropKey() @Composable fun ExplodingFabButton() { val fabSizeState = remember { mutableStateOf(FabSizeState.NORMAL) } val fabTransitionDef = transitionDefinition { // What happens when Normal state(FabSizeState.NORMAL) { this[fabSizeKey] = 80f } // What happens when Exploded state(FabSizeState.EXPLODED) { this[fabSizeKey] = 5000f } } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 @Composable fun ExplodingFabButton() { } enum class FabSizeState { 1 NORMAL, EXPLODED 2 } 3 4 val fabSizeKey = FloatPropKey() 5 6 7 8 val fabSizeState = remember { mutableStateOf(FabSizeState.NORMAL) } 9 10 val fabTransitionDef = transitionDefinition { 11 // What happens when Normal 12 state(FabSizeState.NORMAL) { 13 this[fabSizeKey] = 80f 14 } 15 16 // What happens when Exploded 17 state(FabSizeState.EXPLODED) { 18 this[fabSizeKey] = 5000f 19 } 20 } 21 22 enum class FabSizeState { NORMAL, EXPLODED } 1 2 3 4 val fabSizeKey = FloatPropKey() 5 6 @Composable 7 fun ExplodingFabButton() { 8 val fabSizeState = remember { mutableStateOf(FabSizeState.NORMAL) } 9 10 val fabTransitionDef = transitionDefinition { 11 // What happens when Normal 12 state(FabSizeState.NORMAL) { 13 this[fabSizeKey] = 80f 14 } 15 16 // What happens when Exploded 17 state(FabSizeState.EXPLODED) { 18 this[fabSizeKey] = 5000f 19 } 20 } 21 } 22 25

Slide 69

Slide 69 text

Transitions - 2 enum class FabSizeState { NORMAL, EXPLODED } val fabSizeKey = FloatPropKey() @Composable fun ExplodingFabButton() { val fabSizeState = remember { mutableStateOf(FabSizeState.NORMAL) } val fabTransitionDef = transitionDefinition { // What happens when Normal state(FabSizeState.NORMAL) { this[fabSizeKey] = 80f } // What happens when Exploded state(FabSizeState.EXPLODED) { this[fabSizeKey] = 5000f } } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 @Composable fun ExplodingFabButton() { } enum class FabSizeState { 1 NORMAL, EXPLODED 2 } 3 4 val fabSizeKey = FloatPropKey() 5 6 7 8 val fabSizeState = remember { mutableStateOf(FabSizeState.NORMAL) } 9 10 val fabTransitionDef = transitionDefinition { 11 // What happens when Normal 12 state(FabSizeState.NORMAL) { 13 this[fabSizeKey] = 80f 14 } 15 16 // What happens when Exploded 17 state(FabSizeState.EXPLODED) { 18 this[fabSizeKey] = 5000f 19 } 20 } 21 22 enum class FabSizeState { NORMAL, EXPLODED } 1 2 3 4 val fabSizeKey = FloatPropKey() 5 6 @Composable 7 fun ExplodingFabButton() { 8 val fabSizeState = remember { mutableStateOf(FabSizeState.NORMAL) } 9 10 val fabTransitionDef = transitionDefinition { 11 // What happens when Normal 12 state(FabSizeState.NORMAL) { 13 this[fabSizeKey] = 80f 14 } 15 16 // What happens when Exploded 17 state(FabSizeState.EXPLODED) { 18 this[fabSizeKey] = 5000f 19 } 20 } 21 } 22 val fabSizeKey = FloatPropKey() enum class FabSizeState { 1 NORMAL, EXPLODED 2 } 3 4 5 6 @Composable 7 fun ExplodingFabButton() { 8 val fabSizeState = remember { mutableStateOf(FabSizeState.NORMAL) } 9 10 val fabTransitionDef = transitionDefinition { 11 // What happens when Normal 12 state(FabSizeState.NORMAL) { 13 this[fabSizeKey] = 80f 14 } 15 16 // What happens when Exploded 17 state(FabSizeState.EXPLODED) { 18 this[fabSizeKey] = 5000f 19 } 20 } 21 } 22 25

Slide 70

Slide 70 text

Transitions - 2 enum class FabSizeState { NORMAL, EXPLODED } val fabSizeKey = FloatPropKey() @Composable fun ExplodingFabButton() { val fabSizeState = remember { mutableStateOf(FabSizeState.NORMAL) } val fabTransitionDef = transitionDefinition { // What happens when Normal state(FabSizeState.NORMAL) { this[fabSizeKey] = 80f } // What happens when Exploded state(FabSizeState.EXPLODED) { this[fabSizeKey] = 5000f } } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 @Composable fun ExplodingFabButton() { } enum class FabSizeState { 1 NORMAL, EXPLODED 2 } 3 4 val fabSizeKey = FloatPropKey() 5 6 7 8 val fabSizeState = remember { mutableStateOf(FabSizeState.NORMAL) } 9 10 val fabTransitionDef = transitionDefinition { 11 // What happens when Normal 12 state(FabSizeState.NORMAL) { 13 this[fabSizeKey] = 80f 14 } 15 16 // What happens when Exploded 17 state(FabSizeState.EXPLODED) { 18 this[fabSizeKey] = 5000f 19 } 20 } 21 22 enum class FabSizeState { NORMAL, EXPLODED } 1 2 3 4 val fabSizeKey = FloatPropKey() 5 6 @Composable 7 fun ExplodingFabButton() { 8 val fabSizeState = remember { mutableStateOf(FabSizeState.NORMAL) } 9 10 val fabTransitionDef = transitionDefinition { 11 // What happens when Normal 12 state(FabSizeState.NORMAL) { 13 this[fabSizeKey] = 80f 14 } 15 16 // What happens when Exploded 17 state(FabSizeState.EXPLODED) { 18 this[fabSizeKey] = 5000f 19 } 20 } 21 } 22 val fabSizeKey = FloatPropKey() enum class FabSizeState { 1 NORMAL, EXPLODED 2 } 3 4 5 6 @Composable 7 fun ExplodingFabButton() { 8 val fabSizeState = remember { mutableStateOf(FabSizeState.NORMAL) } 9 10 val fabTransitionDef = transitionDefinition { 11 // What happens when Normal 12 state(FabSizeState.NORMAL) { 13 this[fabSizeKey] = 80f 14 } 15 16 // What happens when Exploded 17 state(FabSizeState.EXPLODED) { 18 this[fabSizeKey] = 5000f 19 } 20 } 21 } 22 val fabSizeState = remember { mutableStateOf(FabSizeState.NORMAL) } enum class FabSizeState { 1 NORMAL, EXPLODED 2 } 3 4 val fabSizeKey = FloatPropKey() 5 6 @Composable 7 fun ExplodingFabButton() { 8 9 10 val fabTransitionDef = transitionDefinition { 11 // What happens when Normal 12 state(FabSizeState.NORMAL) { 13 this[fabSizeKey] = 80f 14 } 15 16 // What happens when Exploded 17 state(FabSizeState.EXPLODED) { 18 this[fabSizeKey] = 5000f 19 } 20 } 21 } 22 25

Slide 71

Slide 71 text

Transitions - 2 enum class FabSizeState { NORMAL, EXPLODED } val fabSizeKey = FloatPropKey() @Composable fun ExplodingFabButton() { val fabSizeState = remember { mutableStateOf(FabSizeState.NORMAL) } val fabTransitionDef = transitionDefinition { // What happens when Normal state(FabSizeState.NORMAL) { this[fabSizeKey] = 80f } // What happens when Exploded state(FabSizeState.EXPLODED) { this[fabSizeKey] = 5000f } } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 @Composable fun ExplodingFabButton() { } enum class FabSizeState { 1 NORMAL, EXPLODED 2 } 3 4 val fabSizeKey = FloatPropKey() 5 6 7 8 val fabSizeState = remember { mutableStateOf(FabSizeState.NORMAL) } 9 10 val fabTransitionDef = transitionDefinition { 11 // What happens when Normal 12 state(FabSizeState.NORMAL) { 13 this[fabSizeKey] = 80f 14 } 15 16 // What happens when Exploded 17 state(FabSizeState.EXPLODED) { 18 this[fabSizeKey] = 5000f 19 } 20 } 21 22 enum class FabSizeState { NORMAL, EXPLODED } 1 2 3 4 val fabSizeKey = FloatPropKey() 5 6 @Composable 7 fun ExplodingFabButton() { 8 val fabSizeState = remember { mutableStateOf(FabSizeState.NORMAL) } 9 10 val fabTransitionDef = transitionDefinition { 11 // What happens when Normal 12 state(FabSizeState.NORMAL) { 13 this[fabSizeKey] = 80f 14 } 15 16 // What happens when Exploded 17 state(FabSizeState.EXPLODED) { 18 this[fabSizeKey] = 5000f 19 } 20 } 21 } 22 val fabSizeKey = FloatPropKey() enum class FabSizeState { 1 NORMAL, EXPLODED 2 } 3 4 5 6 @Composable 7 fun ExplodingFabButton() { 8 val fabSizeState = remember { mutableStateOf(FabSizeState.NORMAL) } 9 10 val fabTransitionDef = transitionDefinition { 11 // What happens when Normal 12 state(FabSizeState.NORMAL) { 13 this[fabSizeKey] = 80f 14 } 15 16 // What happens when Exploded 17 state(FabSizeState.EXPLODED) { 18 this[fabSizeKey] = 5000f 19 } 20 } 21 } 22 val fabSizeState = remember { mutableStateOf(FabSizeState.NORMAL) } enum class FabSizeState { 1 NORMAL, EXPLODED 2 } 3 4 val fabSizeKey = FloatPropKey() 5 6 @Composable 7 fun ExplodingFabButton() { 8 9 10 val fabTransitionDef = transitionDefinition { 11 // What happens when Normal 12 state(FabSizeState.NORMAL) { 13 this[fabSizeKey] = 80f 14 } 15 16 // What happens when Exploded 17 state(FabSizeState.EXPLODED) { 18 this[fabSizeKey] = 5000f 19 } 20 } 21 } 22 val fabTransitionDef = transitionDefinition { } enum class FabSizeState { 1 NORMAL, EXPLODED 2 } 3 4 val fabSizeKey = FloatPropKey() 5 6 @Composable 7 fun ExplodingFabButton() { 8 val fabSizeState = remember { mutableStateOf(FabSizeState.NORMAL) } 9 10 11 // What happens when Normal 12 state(FabSizeState.NORMAL) { 13 this[fabSizeKey] = 80f 14 } 15 16 // What happens when Exploded 17 state(FabSizeState.EXPLODED) { 18 this[fabSizeKey] = 5000f 19 } 20 21 } 22 25

Slide 72

Slide 72 text

Transitions - 2 enum class FabSizeState { NORMAL, EXPLODED } val fabSizeKey = FloatPropKey() @Composable fun ExplodingFabButton() { val fabSizeState = remember { mutableStateOf(FabSizeState.NORMAL) } val fabTransitionDef = transitionDefinition { // What happens when Normal state(FabSizeState.NORMAL) { this[fabSizeKey] = 80f } // What happens when Exploded state(FabSizeState.EXPLODED) { this[fabSizeKey] = 5000f } } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 @Composable fun ExplodingFabButton() { } enum class FabSizeState { 1 NORMAL, EXPLODED 2 } 3 4 val fabSizeKey = FloatPropKey() 5 6 7 8 val fabSizeState = remember { mutableStateOf(FabSizeState.NORMAL) } 9 10 val fabTransitionDef = transitionDefinition { 11 // What happens when Normal 12 state(FabSizeState.NORMAL) { 13 this[fabSizeKey] = 80f 14 } 15 16 // What happens when Exploded 17 state(FabSizeState.EXPLODED) { 18 this[fabSizeKey] = 5000f 19 } 20 } 21 22 enum class FabSizeState { NORMAL, EXPLODED } 1 2 3 4 val fabSizeKey = FloatPropKey() 5 6 @Composable 7 fun ExplodingFabButton() { 8 val fabSizeState = remember { mutableStateOf(FabSizeState.NORMAL) } 9 10 val fabTransitionDef = transitionDefinition { 11 // What happens when Normal 12 state(FabSizeState.NORMAL) { 13 this[fabSizeKey] = 80f 14 } 15 16 // What happens when Exploded 17 state(FabSizeState.EXPLODED) { 18 this[fabSizeKey] = 5000f 19 } 20 } 21 } 22 val fabSizeKey = FloatPropKey() enum class FabSizeState { 1 NORMAL, EXPLODED 2 } 3 4 5 6 @Composable 7 fun ExplodingFabButton() { 8 val fabSizeState = remember { mutableStateOf(FabSizeState.NORMAL) } 9 10 val fabTransitionDef = transitionDefinition { 11 // What happens when Normal 12 state(FabSizeState.NORMAL) { 13 this[fabSizeKey] = 80f 14 } 15 16 // What happens when Exploded 17 state(FabSizeState.EXPLODED) { 18 this[fabSizeKey] = 5000f 19 } 20 } 21 } 22 val fabSizeState = remember { mutableStateOf(FabSizeState.NORMAL) } enum class FabSizeState { 1 NORMAL, EXPLODED 2 } 3 4 val fabSizeKey = FloatPropKey() 5 6 @Composable 7 fun ExplodingFabButton() { 8 9 10 val fabTransitionDef = transitionDefinition { 11 // What happens when Normal 12 state(FabSizeState.NORMAL) { 13 this[fabSizeKey] = 80f 14 } 15 16 // What happens when Exploded 17 state(FabSizeState.EXPLODED) { 18 this[fabSizeKey] = 5000f 19 } 20 } 21 } 22 val fabTransitionDef = transitionDefinition { } enum class FabSizeState { 1 NORMAL, EXPLODED 2 } 3 4 val fabSizeKey = FloatPropKey() 5 6 @Composable 7 fun ExplodingFabButton() { 8 val fabSizeState = remember { mutableStateOf(FabSizeState.NORMAL) } 9 10 11 // What happens when Normal 12 state(FabSizeState.NORMAL) { 13 this[fabSizeKey] = 80f 14 } 15 16 // What happens when Exploded 17 state(FabSizeState.EXPLODED) { 18 this[fabSizeKey] = 5000f 19 } 20 21 } 22 state(FabSizeState.NORMAL) { state(FabSizeState.EXPLODED) { enum class FabSizeState { 1 NORMAL, EXPLODED 2 } 3 4 val fabSizeKey = FloatPropKey() 5 6 @Composable 7 fun ExplodingFabButton() { 8 val fabSizeState = remember { mutableStateOf(FabSizeState.NORMAL) } 9 10 val fabTransitionDef = transitionDefinition { 11 // What happens when Normal 12 13 this[fabSizeKey] = 80f 14 } 15 16 // What happens when Exploded 17 18 this[fabSizeKey] = 5000f 19 } 20 } 21 } 22 25

Slide 73

Slide 73 text

Transitions - 2 enum class FabSizeState { NORMAL, EXPLODED } val fabSizeKey = FloatPropKey() @Composable fun ExplodingFabButton() { val fabSizeState = remember { mutableStateOf(FabSizeState.NORMAL) } val fabTransitionDef = transitionDefinition { // What happens when Normal state(FabSizeState.NORMAL) { this[fabSizeKey] = 80f } // What happens when Exploded state(FabSizeState.EXPLODED) { this[fabSizeKey] = 5000f } } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 @Composable fun ExplodingFabButton() { } enum class FabSizeState { 1 NORMAL, EXPLODED 2 } 3 4 val fabSizeKey = FloatPropKey() 5 6 7 8 val fabSizeState = remember { mutableStateOf(FabSizeState.NORMAL) } 9 10 val fabTransitionDef = transitionDefinition { 11 // What happens when Normal 12 state(FabSizeState.NORMAL) { 13 this[fabSizeKey] = 80f 14 } 15 16 // What happens when Exploded 17 state(FabSizeState.EXPLODED) { 18 this[fabSizeKey] = 5000f 19 } 20 } 21 22 enum class FabSizeState { NORMAL, EXPLODED } 1 2 3 4 val fabSizeKey = FloatPropKey() 5 6 @Composable 7 fun ExplodingFabButton() { 8 val fabSizeState = remember { mutableStateOf(FabSizeState.NORMAL) } 9 10 val fabTransitionDef = transitionDefinition { 11 // What happens when Normal 12 state(FabSizeState.NORMAL) { 13 this[fabSizeKey] = 80f 14 } 15 16 // What happens when Exploded 17 state(FabSizeState.EXPLODED) { 18 this[fabSizeKey] = 5000f 19 } 20 } 21 } 22 val fabSizeKey = FloatPropKey() enum class FabSizeState { 1 NORMAL, EXPLODED 2 } 3 4 5 6 @Composable 7 fun ExplodingFabButton() { 8 val fabSizeState = remember { mutableStateOf(FabSizeState.NORMAL) } 9 10 val fabTransitionDef = transitionDefinition { 11 // What happens when Normal 12 state(FabSizeState.NORMAL) { 13 this[fabSizeKey] = 80f 14 } 15 16 // What happens when Exploded 17 state(FabSizeState.EXPLODED) { 18 this[fabSizeKey] = 5000f 19 } 20 } 21 } 22 val fabSizeState = remember { mutableStateOf(FabSizeState.NORMAL) } enum class FabSizeState { 1 NORMAL, EXPLODED 2 } 3 4 val fabSizeKey = FloatPropKey() 5 6 @Composable 7 fun ExplodingFabButton() { 8 9 10 val fabTransitionDef = transitionDefinition { 11 // What happens when Normal 12 state(FabSizeState.NORMAL) { 13 this[fabSizeKey] = 80f 14 } 15 16 // What happens when Exploded 17 state(FabSizeState.EXPLODED) { 18 this[fabSizeKey] = 5000f 19 } 20 } 21 } 22 val fabTransitionDef = transitionDefinition { } enum class FabSizeState { 1 NORMAL, EXPLODED 2 } 3 4 val fabSizeKey = FloatPropKey() 5 6 @Composable 7 fun ExplodingFabButton() { 8 val fabSizeState = remember { mutableStateOf(FabSizeState.NORMAL) } 9 10 11 // What happens when Normal 12 state(FabSizeState.NORMAL) { 13 this[fabSizeKey] = 80f 14 } 15 16 // What happens when Exploded 17 state(FabSizeState.EXPLODED) { 18 this[fabSizeKey] = 5000f 19 } 20 21 } 22 state(FabSizeState.NORMAL) { state(FabSizeState.EXPLODED) { enum class FabSizeState { 1 NORMAL, EXPLODED 2 } 3 4 val fabSizeKey = FloatPropKey() 5 6 @Composable 7 fun ExplodingFabButton() { 8 val fabSizeState = remember { mutableStateOf(FabSizeState.NORMAL) } 9 10 val fabTransitionDef = transitionDefinition { 11 // What happens when Normal 12 13 this[fabSizeKey] = 80f 14 } 15 16 // What happens when Exploded 17 18 this[fabSizeKey] = 5000f 19 } 20 } 21 } 22 this[fabSizeKey] = 80f this[fabSizeKey] = 5000f enum class FabSizeState { 1 NORMAL, EXPLODED 2 } 3 4 val fabSizeKey = FloatPropKey() 5 6 @Composable 7 fun ExplodingFabButton() { 8 val fabSizeState = remember { mutableStateOf(FabSizeState.NORMAL) } 9 10 val fabTransitionDef = transitionDefinition { 11 // What happens when Normal 12 state(FabSizeState.NORMAL) { 13 14 } 15 16 // What happens when Exploded 17 state(FabSizeState.EXPLODED) { 18 19 } 20 } 21 } 22 25

Slide 74

Slide 74 text

Transitions - 2 enum class FabSizeState { NORMAL, EXPLODED } val fabSizeKey = FloatPropKey() @Composable fun ExplodingFabButton() { val fabSizeState = remember { mutableStateOf(FabSizeState.NORMAL) } val fabTransitionDef = transitionDefinition { // What happens when Normal state(FabSizeState.NORMAL) { this[fabSizeKey] = 80f } // What happens when Exploded state(FabSizeState.EXPLODED) { this[fabSizeKey] = 5000f } } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 @Composable fun ExplodingFabButton() { } enum class FabSizeState { 1 NORMAL, EXPLODED 2 } 3 4 val fabSizeKey = FloatPropKey() 5 6 7 8 val fabSizeState = remember { mutableStateOf(FabSizeState.NORMAL) } 9 10 val fabTransitionDef = transitionDefinition { 11 // What happens when Normal 12 state(FabSizeState.NORMAL) { 13 this[fabSizeKey] = 80f 14 } 15 16 // What happens when Exploded 17 state(FabSizeState.EXPLODED) { 18 this[fabSizeKey] = 5000f 19 } 20 } 21 22 enum class FabSizeState { NORMAL, EXPLODED } 1 2 3 4 val fabSizeKey = FloatPropKey() 5 6 @Composable 7 fun ExplodingFabButton() { 8 val fabSizeState = remember { mutableStateOf(FabSizeState.NORMAL) } 9 10 val fabTransitionDef = transitionDefinition { 11 // What happens when Normal 12 state(FabSizeState.NORMAL) { 13 this[fabSizeKey] = 80f 14 } 15 16 // What happens when Exploded 17 state(FabSizeState.EXPLODED) { 18 this[fabSizeKey] = 5000f 19 } 20 } 21 } 22 val fabSizeKey = FloatPropKey() enum class FabSizeState { 1 NORMAL, EXPLODED 2 } 3 4 5 6 @Composable 7 fun ExplodingFabButton() { 8 val fabSizeState = remember { mutableStateOf(FabSizeState.NORMAL) } 9 10 val fabTransitionDef = transitionDefinition { 11 // What happens when Normal 12 state(FabSizeState.NORMAL) { 13 this[fabSizeKey] = 80f 14 } 15 16 // What happens when Exploded 17 state(FabSizeState.EXPLODED) { 18 this[fabSizeKey] = 5000f 19 } 20 } 21 } 22 val fabSizeState = remember { mutableStateOf(FabSizeState.NORMAL) } enum class FabSizeState { 1 NORMAL, EXPLODED 2 } 3 4 val fabSizeKey = FloatPropKey() 5 6 @Composable 7 fun ExplodingFabButton() { 8 9 10 val fabTransitionDef = transitionDefinition { 11 // What happens when Normal 12 state(FabSizeState.NORMAL) { 13 this[fabSizeKey] = 80f 14 } 15 16 // What happens when Exploded 17 state(FabSizeState.EXPLODED) { 18 this[fabSizeKey] = 5000f 19 } 20 } 21 } 22 val fabTransitionDef = transitionDefinition { } enum class FabSizeState { 1 NORMAL, EXPLODED 2 } 3 4 val fabSizeKey = FloatPropKey() 5 6 @Composable 7 fun ExplodingFabButton() { 8 val fabSizeState = remember { mutableStateOf(FabSizeState.NORMAL) } 9 10 11 // What happens when Normal 12 state(FabSizeState.NORMAL) { 13 this[fabSizeKey] = 80f 14 } 15 16 // What happens when Exploded 17 state(FabSizeState.EXPLODED) { 18 this[fabSizeKey] = 5000f 19 } 20 21 } 22 state(FabSizeState.NORMAL) { state(FabSizeState.EXPLODED) { enum class FabSizeState { 1 NORMAL, EXPLODED 2 } 3 4 val fabSizeKey = FloatPropKey() 5 6 @Composable 7 fun ExplodingFabButton() { 8 val fabSizeState = remember { mutableStateOf(FabSizeState.NORMAL) } 9 10 val fabTransitionDef = transitionDefinition { 11 // What happens when Normal 12 13 this[fabSizeKey] = 80f 14 } 15 16 // What happens when Exploded 17 18 this[fabSizeKey] = 5000f 19 } 20 } 21 } 22 this[fabSizeKey] = 80f this[fabSizeKey] = 5000f enum class FabSizeState { 1 NORMAL, EXPLODED 2 } 3 4 val fabSizeKey = FloatPropKey() 5 6 @Composable 7 fun ExplodingFabButton() { 8 val fabSizeState = remember { mutableStateOf(FabSizeState.NORMAL) } 9 10 val fabTransitionDef = transitionDefinition { 11 // What happens when Normal 12 state(FabSizeState.NORMAL) { 13 14 } 15 16 // What happens when Exploded 17 state(FabSizeState.EXPLODED) { 18 19 } 20 } 21 } 22 enum class FabSizeState { NORMAL, EXPLODED } val fabSizeKey = FloatPropKey() @Composable fun ExplodingFabButton() { val fabSizeState = remember { mutableStateOf(FabSizeState.NORMAL) } val fabTransitionDef = transitionDefinition { // What happens when Normal state(FabSizeState.NORMAL) { this[fabSizeKey] = 80f } // What happens when Exploded state(FabSizeState.EXPLODED) { this[fabSizeKey] = 5000f } } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 25

Slide 75

Slide 75 text

Transitions - 3 @Composable fun ExplodingFabButton() { val fabSizeState = remember { mutableStateOf(FabSizeState.NORMAL) } val fabTransitionDef = transitionDefinition { /* ---- States from Previous Slide ---- */ // Transition from Normal to Exploded transition(FabSizeState.NORMAL to FabSizeState.EXPLODED) { fabSizeKey using keyframes { durationMillis = 1000 80f at 0 35f at 200 5000f at 1000 } } // Transition from Exploded to Normal transition(FabSizeState.EXPLODED to FabSizeState.NORMAL) { fabSizeKey using tween(durationMillis = 1000, easing = FastOutSlowInEasing) } } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 26

Slide 76

Slide 76 text

Transitions - 3 @Composable fun ExplodingFabButton() { val fabSizeState = remember { mutableStateOf(FabSizeState.NORMAL) } val fabTransitionDef = transitionDefinition { /* ---- States from Previous Slide ---- */ // Transition from Normal to Exploded transition(FabSizeState.NORMAL to FabSizeState.EXPLODED) { fabSizeKey using keyframes { durationMillis = 1000 80f at 0 35f at 200 5000f at 1000 } } // Transition from Exploded to Normal transition(FabSizeState.EXPLODED to FabSizeState.NORMAL) { fabSizeKey using tween(durationMillis = 1000, easing = FastOutSlowInEasing) } } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 /* ---- States from Previous Slide ---- */ @Composable 1 fun ExplodingFabButton() { 2 val fabSizeState = remember { mutableStateOf(FabSizeState.NORMAL) } 3 4 val fabTransitionDef = transitionDefinition { 5 6 7 // Transition from Normal to Exploded 8 transition(FabSizeState.NORMAL to FabSizeState.EXPLODED) { 9 fabSizeKey using keyframes { 10 durationMillis = 1000 11 80f at 0 12 35f at 200 13 5000f at 1000 14 } 15 } 16 17 // Transition from Exploded to Normal 18 transition(FabSizeState.EXPLODED to FabSizeState.NORMAL) { 19 fabSizeKey using tween(durationMillis = 1000, 20 easing = FastOutSlowInEasing) 21 } 22 } 23 } 24 26

Slide 77

Slide 77 text

Transitions - 3 @Composable fun ExplodingFabButton() { val fabSizeState = remember { mutableStateOf(FabSizeState.NORMAL) } val fabTransitionDef = transitionDefinition { /* ---- States from Previous Slide ---- */ // Transition from Normal to Exploded transition(FabSizeState.NORMAL to FabSizeState.EXPLODED) { fabSizeKey using keyframes { durationMillis = 1000 80f at 0 35f at 200 5000f at 1000 } } // Transition from Exploded to Normal transition(FabSizeState.EXPLODED to FabSizeState.NORMAL) { fabSizeKey using tween(durationMillis = 1000, easing = FastOutSlowInEasing) } } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 /* ---- States from Previous Slide ---- */ @Composable 1 fun ExplodingFabButton() { 2 val fabSizeState = remember { mutableStateOf(FabSizeState.NORMAL) } 3 4 val fabTransitionDef = transitionDefinition { 5 6 7 // Transition from Normal to Exploded 8 transition(FabSizeState.NORMAL to FabSizeState.EXPLODED) { 9 fabSizeKey using keyframes { 10 durationMillis = 1000 11 80f at 0 12 35f at 200 13 5000f at 1000 14 } 15 } 16 17 // Transition from Exploded to Normal 18 transition(FabSizeState.EXPLODED to FabSizeState.NORMAL) { 19 fabSizeKey using tween(durationMillis = 1000, 20 easing = FastOutSlowInEasing) 21 } 22 } 23 } 24 // Transition from Normal to Exploded transition(FabSizeState.NORMAL to FabSizeState.EXPLODED) { // Transition from Exploded to Normal transition(FabSizeState.EXPLODED to FabSizeState.NORMAL) { @Composable 1 fun ExplodingFabButton() { 2 val fabSizeState = remember { mutableStateOf(FabSizeState.NORMAL) } 3 4 val fabTransitionDef = transitionDefinition { 5 /* ---- States from Previous Slide ---- */ 6 7 8 9 fabSizeKey using keyframes { 10 durationMillis = 1000 11 80f at 0 12 35f at 200 13 5000f at 1000 14 } 15 } 16 17 18 19 fabSizeKey using tween(durationMillis = 1000, 20 easing = FastOutSlowInEasing) 21 } 22 } 23 } 24 26

Slide 78

Slide 78 text

Transitions - 3 @Composable fun ExplodingFabButton() { val fabSizeState = remember { mutableStateOf(FabSizeState.NORMAL) } val fabTransitionDef = transitionDefinition { /* ---- States from Previous Slide ---- */ // Transition from Normal to Exploded transition(FabSizeState.NORMAL to FabSizeState.EXPLODED) { fabSizeKey using keyframes { durationMillis = 1000 80f at 0 35f at 200 5000f at 1000 } } // Transition from Exploded to Normal transition(FabSizeState.EXPLODED to FabSizeState.NORMAL) { fabSizeKey using tween(durationMillis = 1000, easing = FastOutSlowInEasing) } } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 /* ---- States from Previous Slide ---- */ @Composable 1 fun ExplodingFabButton() { 2 val fabSizeState = remember { mutableStateOf(FabSizeState.NORMAL) } 3 4 val fabTransitionDef = transitionDefinition { 5 6 7 // Transition from Normal to Exploded 8 transition(FabSizeState.NORMAL to FabSizeState.EXPLODED) { 9 fabSizeKey using keyframes { 10 durationMillis = 1000 11 80f at 0 12 35f at 200 13 5000f at 1000 14 } 15 } 16 17 // Transition from Exploded to Normal 18 transition(FabSizeState.EXPLODED to FabSizeState.NORMAL) { 19 fabSizeKey using tween(durationMillis = 1000, 20 easing = FastOutSlowInEasing) 21 } 22 } 23 } 24 // Transition from Normal to Exploded transition(FabSizeState.NORMAL to FabSizeState.EXPLODED) { // Transition from Exploded to Normal transition(FabSizeState.EXPLODED to FabSizeState.NORMAL) { @Composable 1 fun ExplodingFabButton() { 2 val fabSizeState = remember { mutableStateOf(FabSizeState.NORMAL) } 3 4 val fabTransitionDef = transitionDefinition { 5 /* ---- States from Previous Slide ---- */ 6 7 8 9 fabSizeKey using keyframes { 10 durationMillis = 1000 11 80f at 0 12 35f at 200 13 5000f at 1000 14 } 15 } 16 17 18 19 fabSizeKey using tween(durationMillis = 1000, 20 easing = FastOutSlowInEasing) 21 } 22 } 23 } 24 fabSizeKey using keyframes { durationMillis = 1000 80f at 0 35f at 200 5000f at 1000 } @Composable 1 fun ExplodingFabButton() { 2 val fabSizeState = remember { mutableStateOf(FabSizeState.NORMAL) } 3 4 val fabTransitionDef = transitionDefinition { 5 /* ---- States from Previous Slide ---- */ 6 7 // Transition from Normal to Exploded 8 transition(FabSizeState.NORMAL to FabSizeState.EXPLODED) { 9 10 11 12 13 14 15 } 16 17 // Transition from Exploded to Normal 18 transition(FabSizeState.EXPLODED to FabSizeState.NORMAL) { 19 fabSizeKey using tween(durationMillis = 1000, 20 easing = FastOutSlowInEasing) 21 } 22 } 23 } 24 26

Slide 79

Slide 79 text

Transitions - 3 @Composable fun ExplodingFabButton() { val fabSizeState = remember { mutableStateOf(FabSizeState.NORMAL) } val fabTransitionDef = transitionDefinition { /* ---- States from Previous Slide ---- */ // Transition from Normal to Exploded transition(FabSizeState.NORMAL to FabSizeState.EXPLODED) { fabSizeKey using keyframes { durationMillis = 1000 80f at 0 35f at 200 5000f at 1000 } } // Transition from Exploded to Normal transition(FabSizeState.EXPLODED to FabSizeState.NORMAL) { fabSizeKey using tween(durationMillis = 1000, easing = FastOutSlowInEasing) } } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 /* ---- States from Previous Slide ---- */ @Composable 1 fun ExplodingFabButton() { 2 val fabSizeState = remember { mutableStateOf(FabSizeState.NORMAL) } 3 4 val fabTransitionDef = transitionDefinition { 5 6 7 // Transition from Normal to Exploded 8 transition(FabSizeState.NORMAL to FabSizeState.EXPLODED) { 9 fabSizeKey using keyframes { 10 durationMillis = 1000 11 80f at 0 12 35f at 200 13 5000f at 1000 14 } 15 } 16 17 // Transition from Exploded to Normal 18 transition(FabSizeState.EXPLODED to FabSizeState.NORMAL) { 19 fabSizeKey using tween(durationMillis = 1000, 20 easing = FastOutSlowInEasing) 21 } 22 } 23 } 24 // Transition from Normal to Exploded transition(FabSizeState.NORMAL to FabSizeState.EXPLODED) { // Transition from Exploded to Normal transition(FabSizeState.EXPLODED to FabSizeState.NORMAL) { @Composable 1 fun ExplodingFabButton() { 2 val fabSizeState = remember { mutableStateOf(FabSizeState.NORMAL) } 3 4 val fabTransitionDef = transitionDefinition { 5 /* ---- States from Previous Slide ---- */ 6 7 8 9 fabSizeKey using keyframes { 10 durationMillis = 1000 11 80f at 0 12 35f at 200 13 5000f at 1000 14 } 15 } 16 17 18 19 fabSizeKey using tween(durationMillis = 1000, 20 easing = FastOutSlowInEasing) 21 } 22 } 23 } 24 fabSizeKey using keyframes { durationMillis = 1000 80f at 0 35f at 200 5000f at 1000 } @Composable 1 fun ExplodingFabButton() { 2 val fabSizeState = remember { mutableStateOf(FabSizeState.NORMAL) } 3 4 val fabTransitionDef = transitionDefinition { 5 /* ---- States from Previous Slide ---- */ 6 7 // Transition from Normal to Exploded 8 transition(FabSizeState.NORMAL to FabSizeState.EXPLODED) { 9 10 11 12 13 14 15 } 16 17 // Transition from Exploded to Normal 18 transition(FabSizeState.EXPLODED to FabSizeState.NORMAL) { 19 fabSizeKey using tween(durationMillis = 1000, 20 easing = FastOutSlowInEasing) 21 } 22 } 23 } 24 fabSizeKey using tween(durationMillis = 1000, easing = FastOutSlowInEasing) @Composable 1 fun ExplodingFabButton() { 2 val fabSizeState = remember { mutableStateOf(FabSizeState.NORMAL) } 3 4 val fabTransitionDef = transitionDefinition { 5 /* ---- States from Previous Slide ---- */ 6 7 // Transition from Normal to Exploded 8 transition(FabSizeState.NORMAL to FabSizeState.EXPLODED) { 9 fabSizeKey using keyframes { 10 durationMillis = 1000 11 80f at 0 12 35f at 200 13 5000f at 1000 14 } 15 } 16 17 // Transition from Exploded to Normal 18 transition(FabSizeState.EXPLODED to FabSizeState.NORMAL) { 19 20 21 } 22 } 23 } 24 26

Slide 80

Slide 80 text

Transitions - 3 @Composable fun ExplodingFabButton() { val fabSizeState = remember { mutableStateOf(FabSizeState.NORMAL) } val fabTransitionDef = transitionDefinition { /* ---- States from Previous Slide ---- */ // Transition from Normal to Exploded transition(FabSizeState.NORMAL to FabSizeState.EXPLODED) { fabSizeKey using keyframes { durationMillis = 1000 80f at 0 35f at 200 5000f at 1000 } } // Transition from Exploded to Normal transition(FabSizeState.EXPLODED to FabSizeState.NORMAL) { fabSizeKey using tween(durationMillis = 1000, easing = FastOutSlowInEasing) } } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 /* ---- States from Previous Slide ---- */ @Composable 1 fun ExplodingFabButton() { 2 val fabSizeState = remember { mutableStateOf(FabSizeState.NORMAL) } 3 4 val fabTransitionDef = transitionDefinition { 5 6 7 // Transition from Normal to Exploded 8 transition(FabSizeState.NORMAL to FabSizeState.EXPLODED) { 9 fabSizeKey using keyframes { 10 durationMillis = 1000 11 80f at 0 12 35f at 200 13 5000f at 1000 14 } 15 } 16 17 // Transition from Exploded to Normal 18 transition(FabSizeState.EXPLODED to FabSizeState.NORMAL) { 19 fabSizeKey using tween(durationMillis = 1000, 20 easing = FastOutSlowInEasing) 21 } 22 } 23 } 24 // Transition from Normal to Exploded transition(FabSizeState.NORMAL to FabSizeState.EXPLODED) { // Transition from Exploded to Normal transition(FabSizeState.EXPLODED to FabSizeState.NORMAL) { @Composable 1 fun ExplodingFabButton() { 2 val fabSizeState = remember { mutableStateOf(FabSizeState.NORMAL) } 3 4 val fabTransitionDef = transitionDefinition { 5 /* ---- States from Previous Slide ---- */ 6 7 8 9 fabSizeKey using keyframes { 10 durationMillis = 1000 11 80f at 0 12 35f at 200 13 5000f at 1000 14 } 15 } 16 17 18 19 fabSizeKey using tween(durationMillis = 1000, 20 easing = FastOutSlowInEasing) 21 } 22 } 23 } 24 fabSizeKey using keyframes { durationMillis = 1000 80f at 0 35f at 200 5000f at 1000 } @Composable 1 fun ExplodingFabButton() { 2 val fabSizeState = remember { mutableStateOf(FabSizeState.NORMAL) } 3 4 val fabTransitionDef = transitionDefinition { 5 /* ---- States from Previous Slide ---- */ 6 7 // Transition from Normal to Exploded 8 transition(FabSizeState.NORMAL to FabSizeState.EXPLODED) { 9 10 11 12 13 14 15 } 16 17 // Transition from Exploded to Normal 18 transition(FabSizeState.EXPLODED to FabSizeState.NORMAL) { 19 fabSizeKey using tween(durationMillis = 1000, 20 easing = FastOutSlowInEasing) 21 } 22 } 23 } 24 fabSizeKey using tween(durationMillis = 1000, easing = FastOutSlowInEasing) @Composable 1 fun ExplodingFabButton() { 2 val fabSizeState = remember { mutableStateOf(FabSizeState.NORMAL) } 3 4 val fabTransitionDef = transitionDefinition { 5 /* ---- States from Previous Slide ---- */ 6 7 // Transition from Normal to Exploded 8 transition(FabSizeState.NORMAL to FabSizeState.EXPLODED) { 9 fabSizeKey using keyframes { 10 durationMillis = 1000 11 80f at 0 12 35f at 200 13 5000f at 1000 14 } 15 } 16 17 // Transition from Exploded to Normal 18 transition(FabSizeState.EXPLODED to FabSizeState.NORMAL) { 19 20 21 } 22 } 23 } 24 @Composable fun ExplodingFabButton() { val fabSizeState = remember { mutableStateOf(FabSizeState.NORMAL) } val fabTransitionDef = transitionDefinition { /* ---- States from Previous Slide ---- */ // Transition from Normal to Exploded transition(FabSizeState.NORMAL to FabSizeState.EXPLODED) { fabSizeKey using keyframes { durationMillis = 1000 80f at 0 35f at 200 5000f at 1000 } } // Transition from Exploded to Normal transition(FabSizeState.EXPLODED to FabSizeState.NORMAL) { fabSizeKey using tween(durationMillis = 1000, easing = FastOutSlowInEasing) } } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 26

Slide 81

Slide 81 text

Transitions - 4 @Composable fun ExplodingFabButton() { val fabSizeState = remember { mutableStateOf(FabSizeState.NORMAL) } val fabTransitionDef = transitionDefinition { /* ---- States from Previous Slide ---- */ /* ---- Transitions from Previous Slide ---- */ } val transitionState = transition( definition = fabTransitionDef, initState = fabSizeState.value, toState = if (fabSizeState.value == FabSizeState.NORMAL) FabSizeState.EXPLODED else FabSizeState.NORMAL ) FabButton(fabSizeState = fabSizeState, transitionState = transitionState) } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 27

Slide 82

Slide 82 text

Transitions - 4 @Composable fun ExplodingFabButton() { val fabSizeState = remember { mutableStateOf(FabSizeState.NORMAL) } val fabTransitionDef = transitionDefinition { /* ---- States from Previous Slide ---- */ /* ---- Transitions from Previous Slide ---- */ } val transitionState = transition( definition = fabTransitionDef, initState = fabSizeState.value, toState = if (fabSizeState.value == FabSizeState.NORMAL) FabSizeState.EXPLODED else FabSizeState.NORMAL ) FabButton(fabSizeState = fabSizeState, transitionState = transitionState) } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 val fabTransitionDef = transitionDefinition { /* ---- States from Previous Slide ---- */ /* ---- Transitions from Previous Slide ---- */ } @Composable 1 fun ExplodingFabButton() { 2 val fabSizeState = remember { mutableStateOf(FabSizeState.NORMAL) } 3 4 5 6 7 8 9 10 val transitionState = transition( 11 definition = fabTransitionDef, 12 initState = fabSizeState.value, 13 toState = if (fabSizeState.value == FabSizeState.NORMAL) 14 FabSizeState.EXPLODED 15 else FabSizeState.NORMAL 16 ) 17 18 FabButton(fabSizeState = fabSizeState, transitionState = transitionState) 19 } 20 27

Slide 83

Slide 83 text

Transitions - 4 @Composable fun ExplodingFabButton() { val fabSizeState = remember { mutableStateOf(FabSizeState.NORMAL) } val fabTransitionDef = transitionDefinition { /* ---- States from Previous Slide ---- */ /* ---- Transitions from Previous Slide ---- */ } val transitionState = transition( definition = fabTransitionDef, initState = fabSizeState.value, toState = if (fabSizeState.value == FabSizeState.NORMAL) FabSizeState.EXPLODED else FabSizeState.NORMAL ) FabButton(fabSizeState = fabSizeState, transitionState = transitionState) } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 val fabTransitionDef = transitionDefinition { /* ---- States from Previous Slide ---- */ /* ---- Transitions from Previous Slide ---- */ } @Composable 1 fun ExplodingFabButton() { 2 val fabSizeState = remember { mutableStateOf(FabSizeState.NORMAL) } 3 4 5 6 7 8 9 10 val transitionState = transition( 11 definition = fabTransitionDef, 12 initState = fabSizeState.value, 13 toState = if (fabSizeState.value == FabSizeState.NORMAL) 14 FabSizeState.EXPLODED 15 else FabSizeState.NORMAL 16 ) 17 18 FabButton(fabSizeState = fabSizeState, transitionState = transitionState) 19 } 20 val transitionState = transition( @Composable 1 fun ExplodingFabButton() { 2 val fabSizeState = remember { mutableStateOf(FabSizeState.NORMAL) } 3 4 val fabTransitionDef = transitionDefinition { 5 /* ---- States from Previous Slide ---- */ 6 7 /* ---- Transitions from Previous Slide ---- */ 8 } 9 10 11 definition = fabTransitionDef, 12 initState = fabSizeState.value, 13 toState = if (fabSizeState.value == FabSizeState.NORMAL) 14 FabSizeState.EXPLODED 15 else FabSizeState.NORMAL 16 ) 17 18 FabButton(fabSizeState = fabSizeState, transitionState = transitionState) 19 } 20 27

Slide 84

Slide 84 text

Transitions - 4 @Composable fun ExplodingFabButton() { val fabSizeState = remember { mutableStateOf(FabSizeState.NORMAL) } val fabTransitionDef = transitionDefinition { /* ---- States from Previous Slide ---- */ /* ---- Transitions from Previous Slide ---- */ } val transitionState = transition( definition = fabTransitionDef, initState = fabSizeState.value, toState = if (fabSizeState.value == FabSizeState.NORMAL) FabSizeState.EXPLODED else FabSizeState.NORMAL ) FabButton(fabSizeState = fabSizeState, transitionState = transitionState) } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 val fabTransitionDef = transitionDefinition { /* ---- States from Previous Slide ---- */ /* ---- Transitions from Previous Slide ---- */ } @Composable 1 fun ExplodingFabButton() { 2 val fabSizeState = remember { mutableStateOf(FabSizeState.NORMAL) } 3 4 5 6 7 8 9 10 val transitionState = transition( 11 definition = fabTransitionDef, 12 initState = fabSizeState.value, 13 toState = if (fabSizeState.value == FabSizeState.NORMAL) 14 FabSizeState.EXPLODED 15 else FabSizeState.NORMAL 16 ) 17 18 FabButton(fabSizeState = fabSizeState, transitionState = transitionState) 19 } 20 val transitionState = transition( @Composable 1 fun ExplodingFabButton() { 2 val fabSizeState = remember { mutableStateOf(FabSizeState.NORMAL) } 3 4 val fabTransitionDef = transitionDefinition { 5 /* ---- States from Previous Slide ---- */ 6 7 /* ---- Transitions from Previous Slide ---- */ 8 } 9 10 11 definition = fabTransitionDef, 12 initState = fabSizeState.value, 13 toState = if (fabSizeState.value == FabSizeState.NORMAL) 14 FabSizeState.EXPLODED 15 else FabSizeState.NORMAL 16 ) 17 18 FabButton(fabSizeState = fabSizeState, transitionState = transitionState) 19 } 20 val fabTransitionDef = transitionDefinition { definition = fabTransitionDef, @Composable 1 fun ExplodingFabButton() { 2 val fabSizeState = remember { mutableStateOf(FabSizeState.NORMAL) } 3 4 5 /* ---- States from Previous Slide ---- */ 6 7 /* ---- Transitions from Previous Slide ---- */ 8 } 9 10 val transitionState = transition( 11 12 initState = fabSizeState.value, 13 toState = if (fabSizeState.value == FabSizeState.NORMAL) 14 FabSizeState.EXPLODED 15 else FabSizeState.NORMAL 16 ) 17 18 FabButton(fabSizeState = fabSizeState, transitionState = transitionState) 19 } 20 27

Slide 85

Slide 85 text

Transitions - 4 @Composable fun ExplodingFabButton() { val fabSizeState = remember { mutableStateOf(FabSizeState.NORMAL) } val fabTransitionDef = transitionDefinition { /* ---- States from Previous Slide ---- */ /* ---- Transitions from Previous Slide ---- */ } val transitionState = transition( definition = fabTransitionDef, initState = fabSizeState.value, toState = if (fabSizeState.value == FabSizeState.NORMAL) FabSizeState.EXPLODED else FabSizeState.NORMAL ) FabButton(fabSizeState = fabSizeState, transitionState = transitionState) } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 val fabTransitionDef = transitionDefinition { /* ---- States from Previous Slide ---- */ /* ---- Transitions from Previous Slide ---- */ } @Composable 1 fun ExplodingFabButton() { 2 val fabSizeState = remember { mutableStateOf(FabSizeState.NORMAL) } 3 4 5 6 7 8 9 10 val transitionState = transition( 11 definition = fabTransitionDef, 12 initState = fabSizeState.value, 13 toState = if (fabSizeState.value == FabSizeState.NORMAL) 14 FabSizeState.EXPLODED 15 else FabSizeState.NORMAL 16 ) 17 18 FabButton(fabSizeState = fabSizeState, transitionState = transitionState) 19 } 20 val transitionState = transition( @Composable 1 fun ExplodingFabButton() { 2 val fabSizeState = remember { mutableStateOf(FabSizeState.NORMAL) } 3 4 val fabTransitionDef = transitionDefinition { 5 /* ---- States from Previous Slide ---- */ 6 7 /* ---- Transitions from Previous Slide ---- */ 8 } 9 10 11 definition = fabTransitionDef, 12 initState = fabSizeState.value, 13 toState = if (fabSizeState.value == FabSizeState.NORMAL) 14 FabSizeState.EXPLODED 15 else FabSizeState.NORMAL 16 ) 17 18 FabButton(fabSizeState = fabSizeState, transitionState = transitionState) 19 } 20 val fabTransitionDef = transitionDefinition { definition = fabTransitionDef, @Composable 1 fun ExplodingFabButton() { 2 val fabSizeState = remember { mutableStateOf(FabSizeState.NORMAL) } 3 4 5 /* ---- States from Previous Slide ---- */ 6 7 /* ---- Transitions from Previous Slide ---- */ 8 } 9 10 val transitionState = transition( 11 12 initState = fabSizeState.value, 13 toState = if (fabSizeState.value == FabSizeState.NORMAL) 14 FabSizeState.EXPLODED 15 else FabSizeState.NORMAL 16 ) 17 18 FabButton(fabSizeState = fabSizeState, transitionState = transitionState) 19 } 20 val fabSizeState = remember { mutableStateOf(FabSizeState.NORMAL) } initState = fabSizeState.value, @Composable 1 fun ExplodingFabButton() { 2 3 4 val fabTransitionDef = transitionDefinition { 5 /* ---- States from Previous Slide ---- */ 6 7 /* ---- Transitions from Previous Slide ---- */ 8 } 9 10 val transitionState = transition( 11 definition = fabTransitionDef, 12 13 toState = if (fabSizeState.value == FabSizeState.NORMAL) 14 FabSizeState.EXPLODED 15 else FabSizeState.NORMAL 16 ) 17 18 FabButton(fabSizeState = fabSizeState, transitionState = transitionState) 19 } 20 27

Slide 86

Slide 86 text

Transitions - 4 @Composable fun ExplodingFabButton() { val fabSizeState = remember { mutableStateOf(FabSizeState.NORMAL) } val fabTransitionDef = transitionDefinition { /* ---- States from Previous Slide ---- */ /* ---- Transitions from Previous Slide ---- */ } val transitionState = transition( definition = fabTransitionDef, initState = fabSizeState.value, toState = if (fabSizeState.value == FabSizeState.NORMAL) FabSizeState.EXPLODED else FabSizeState.NORMAL ) FabButton(fabSizeState = fabSizeState, transitionState = transitionState) } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 val fabTransitionDef = transitionDefinition { /* ---- States from Previous Slide ---- */ /* ---- Transitions from Previous Slide ---- */ } @Composable 1 fun ExplodingFabButton() { 2 val fabSizeState = remember { mutableStateOf(FabSizeState.NORMAL) } 3 4 5 6 7 8 9 10 val transitionState = transition( 11 definition = fabTransitionDef, 12 initState = fabSizeState.value, 13 toState = if (fabSizeState.value == FabSizeState.NORMAL) 14 FabSizeState.EXPLODED 15 else FabSizeState.NORMAL 16 ) 17 18 FabButton(fabSizeState = fabSizeState, transitionState = transitionState) 19 } 20 val transitionState = transition( @Composable 1 fun ExplodingFabButton() { 2 val fabSizeState = remember { mutableStateOf(FabSizeState.NORMAL) } 3 4 val fabTransitionDef = transitionDefinition { 5 /* ---- States from Previous Slide ---- */ 6 7 /* ---- Transitions from Previous Slide ---- */ 8 } 9 10 11 definition = fabTransitionDef, 12 initState = fabSizeState.value, 13 toState = if (fabSizeState.value == FabSizeState.NORMAL) 14 FabSizeState.EXPLODED 15 else FabSizeState.NORMAL 16 ) 17 18 FabButton(fabSizeState = fabSizeState, transitionState = transitionState) 19 } 20 val fabTransitionDef = transitionDefinition { definition = fabTransitionDef, @Composable 1 fun ExplodingFabButton() { 2 val fabSizeState = remember { mutableStateOf(FabSizeState.NORMAL) } 3 4 5 /* ---- States from Previous Slide ---- */ 6 7 /* ---- Transitions from Previous Slide ---- */ 8 } 9 10 val transitionState = transition( 11 12 initState = fabSizeState.value, 13 toState = if (fabSizeState.value == FabSizeState.NORMAL) 14 FabSizeState.EXPLODED 15 else FabSizeState.NORMAL 16 ) 17 18 FabButton(fabSizeState = fabSizeState, transitionState = transitionState) 19 } 20 val fabSizeState = remember { mutableStateOf(FabSizeState.NORMAL) } initState = fabSizeState.value, @Composable 1 fun ExplodingFabButton() { 2 3 4 val fabTransitionDef = transitionDefinition { 5 /* ---- States from Previous Slide ---- */ 6 7 /* ---- Transitions from Previous Slide ---- */ 8 } 9 10 val transitionState = transition( 11 definition = fabTransitionDef, 12 13 toState = if (fabSizeState.value == FabSizeState.NORMAL) 14 FabSizeState.EXPLODED 15 else FabSizeState.NORMAL 16 ) 17 18 FabButton(fabSizeState = fabSizeState, transitionState = transitionState) 19 } 20 toState = if (fabSizeState.value == FabSizeState.NORMAL) FabSizeState.EXPLODED else FabSizeState.NORMAL @Composable 1 fun ExplodingFabButton() { 2 val fabSizeState = remember { mutableStateOf(FabSizeState.NORMAL) } 3 4 val fabTransitionDef = transitionDefinition { 5 /* ---- States from Previous Slide ---- */ 6 7 /* ---- Transitions from Previous Slide ---- */ 8 } 9 10 val transitionState = transition( 11 definition = fabTransitionDef, 12 initState = fabSizeState.value, 13 14 15 16 ) 17 18 FabButton(fabSizeState = fabSizeState, transitionState = transitionState) 19 } 20 27

Slide 87

Slide 87 text

Transitions - 4 @Composable fun ExplodingFabButton() { val fabSizeState = remember { mutableStateOf(FabSizeState.NORMAL) } val fabTransitionDef = transitionDefinition { /* ---- States from Previous Slide ---- */ /* ---- Transitions from Previous Slide ---- */ } val transitionState = transition( definition = fabTransitionDef, initState = fabSizeState.value, toState = if (fabSizeState.value == FabSizeState.NORMAL) FabSizeState.EXPLODED else FabSizeState.NORMAL ) FabButton(fabSizeState = fabSizeState, transitionState = transitionState) } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 val fabTransitionDef = transitionDefinition { /* ---- States from Previous Slide ---- */ /* ---- Transitions from Previous Slide ---- */ } @Composable 1 fun ExplodingFabButton() { 2 val fabSizeState = remember { mutableStateOf(FabSizeState.NORMAL) } 3 4 5 6 7 8 9 10 val transitionState = transition( 11 definition = fabTransitionDef, 12 initState = fabSizeState.value, 13 toState = if (fabSizeState.value == FabSizeState.NORMAL) 14 FabSizeState.EXPLODED 15 else FabSizeState.NORMAL 16 ) 17 18 FabButton(fabSizeState = fabSizeState, transitionState = transitionState) 19 } 20 val transitionState = transition( @Composable 1 fun ExplodingFabButton() { 2 val fabSizeState = remember { mutableStateOf(FabSizeState.NORMAL) } 3 4 val fabTransitionDef = transitionDefinition { 5 /* ---- States from Previous Slide ---- */ 6 7 /* ---- Transitions from Previous Slide ---- */ 8 } 9 10 11 definition = fabTransitionDef, 12 initState = fabSizeState.value, 13 toState = if (fabSizeState.value == FabSizeState.NORMAL) 14 FabSizeState.EXPLODED 15 else FabSizeState.NORMAL 16 ) 17 18 FabButton(fabSizeState = fabSizeState, transitionState = transitionState) 19 } 20 val fabTransitionDef = transitionDefinition { definition = fabTransitionDef, @Composable 1 fun ExplodingFabButton() { 2 val fabSizeState = remember { mutableStateOf(FabSizeState.NORMAL) } 3 4 5 /* ---- States from Previous Slide ---- */ 6 7 /* ---- Transitions from Previous Slide ---- */ 8 } 9 10 val transitionState = transition( 11 12 initState = fabSizeState.value, 13 toState = if (fabSizeState.value == FabSizeState.NORMAL) 14 FabSizeState.EXPLODED 15 else FabSizeState.NORMAL 16 ) 17 18 FabButton(fabSizeState = fabSizeState, transitionState = transitionState) 19 } 20 val fabSizeState = remember { mutableStateOf(FabSizeState.NORMAL) } initState = fabSizeState.value, @Composable 1 fun ExplodingFabButton() { 2 3 4 val fabTransitionDef = transitionDefinition { 5 /* ---- States from Previous Slide ---- */ 6 7 /* ---- Transitions from Previous Slide ---- */ 8 } 9 10 val transitionState = transition( 11 definition = fabTransitionDef, 12 13 toState = if (fabSizeState.value == FabSizeState.NORMAL) 14 FabSizeState.EXPLODED 15 else FabSizeState.NORMAL 16 ) 17 18 FabButton(fabSizeState = fabSizeState, transitionState = transitionState) 19 } 20 toState = if (fabSizeState.value == FabSizeState.NORMAL) FabSizeState.EXPLODED else FabSizeState.NORMAL @Composable 1 fun ExplodingFabButton() { 2 val fabSizeState = remember { mutableStateOf(FabSizeState.NORMAL) } 3 4 val fabTransitionDef = transitionDefinition { 5 /* ---- States from Previous Slide ---- */ 6 7 /* ---- Transitions from Previous Slide ---- */ 8 } 9 10 val transitionState = transition( 11 definition = fabTransitionDef, 12 initState = fabSizeState.value, 13 14 15 16 ) 17 18 FabButton(fabSizeState = fabSizeState, transitionState = transitionState) 19 } 20 FabButton(fabSizeState = fabSizeState, transitionState = transitionState) @Composable 1 fun ExplodingFabButton() { 2 val fabSizeState = remember { mutableStateOf(FabSizeState.NORMAL) } 3 4 val fabTransitionDef = transitionDefinition { 5 /* ---- States from Previous Slide ---- */ 6 7 /* ---- Transitions from Previous Slide ---- */ 8 } 9 10 val transitionState = transition( 11 definition = fabTransitionDef, 12 initState = fabSizeState.value, 13 toState = if (fabSizeState.value == FabSizeState.NORMAL) 14 FabSizeState.EXPLODED 15 else FabSizeState.NORMAL 16 ) 17 18 19 } 20 27

Slide 88

Slide 88 text

Transitions - 5 @Composable fun ExplodingFabButton() { /* From Previous Slides */ } @Composable fun FabButton(fabSizeState: MutableState, transitionState: TransitionState ) { FloatingActionButton( onClick = { }, modifier = Modifier.size(transitionState[fabSizeKey].dp) ) { Icon(asset = Icons.Default.Add) } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 28

Slide 89

Slide 89 text

Transitions - 5 @Composable fun ExplodingFabButton() { /* From Previous Slides */ } @Composable fun FabButton(fabSizeState: MutableState, transitionState: TransitionState ) { FloatingActionButton( onClick = { }, modifier = Modifier.size(transitionState[fabSizeKey].dp) ) { Icon(asset = Icons.Default.Add) } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 fun ExplodingFabButton() { /* From Previous Slides */ } @Composable 1 2 3 4 5 @Composable 6 fun FabButton(fabSizeState: MutableState, 7 transitionState: TransitionState 8 ) { 9 FloatingActionButton( 10 onClick = { }, 11 modifier = Modifier.size(transitionState[fabSizeKey].dp) 12 ) { 13 Icon(asset = Icons.Default.Add) 14 } 15 } 16 28

Slide 90

Slide 90 text

Transitions - 5 @Composable fun ExplodingFabButton() { /* From Previous Slides */ } @Composable fun FabButton(fabSizeState: MutableState, transitionState: TransitionState ) { FloatingActionButton( onClick = { }, modifier = Modifier.size(transitionState[fabSizeKey].dp) ) { Icon(asset = Icons.Default.Add) } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 fun ExplodingFabButton() { /* From Previous Slides */ } @Composable 1 2 3 4 5 @Composable 6 fun FabButton(fabSizeState: MutableState, 7 transitionState: TransitionState 8 ) { 9 FloatingActionButton( 10 onClick = { }, 11 modifier = Modifier.size(transitionState[fabSizeKey].dp) 12 ) { 13 Icon(asset = Icons.Default.Add) 14 } 15 } 16 fun FabButton(fabSizeState: MutableState, FloatingActionButton( Icon(asset = Icons.Default.Add) @Composable 1 fun ExplodingFabButton() { 2 /* From Previous Slides */ 3 } 4 5 @Composable 6 7 transitionState: TransitionState 8 ) { 9 10 onClick = { }, 11 modifier = Modifier.size(transitionState[fabSizeKey].dp) 12 ) { 13 14 } 15 } 16 28

Slide 91

Slide 91 text

Transitions - 5 @Composable fun ExplodingFabButton() { /* From Previous Slides */ } @Composable fun FabButton(fabSizeState: MutableState, transitionState: TransitionState ) { FloatingActionButton( onClick = { }, modifier = Modifier.size(transitionState[fabSizeKey].dp) ) { Icon(asset = Icons.Default.Add) } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 fun ExplodingFabButton() { /* From Previous Slides */ } @Composable 1 2 3 4 5 @Composable 6 fun FabButton(fabSizeState: MutableState, 7 transitionState: TransitionState 8 ) { 9 FloatingActionButton( 10 onClick = { }, 11 modifier = Modifier.size(transitionState[fabSizeKey].dp) 12 ) { 13 Icon(asset = Icons.Default.Add) 14 } 15 } 16 fun FabButton(fabSizeState: MutableState, FloatingActionButton( Icon(asset = Icons.Default.Add) @Composable 1 fun ExplodingFabButton() { 2 /* From Previous Slides */ 3 } 4 5 @Composable 6 7 transitionState: TransitionState 8 ) { 9 10 onClick = { }, 11 modifier = Modifier.size(transitionState[fabSizeKey].dp) 12 ) { 13 14 } 15 } 16 transitionState: TransitionState modifier = Modifier.size(transitionState[fabSizeKey].dp) @Composable 1 fun ExplodingFabButton() { 2 /* From Previous Slides */ 3 } 4 5 @Composable 6 fun FabButton(fabSizeState: MutableState, 7 8 ) { 9 FloatingActionButton( 10 onClick = { }, 11 12 ) { 13 Icon(asset = Icons.Default.Add) 14 } 15 } 16 28

Slide 92

Slide 92 text

Transitions - Examples By Joe Birch By Ray Wenderlich https://joebirch.co/ https://www.raywenderlich.com/13282144-jetpack-compose- animations-tutorial-getting-started By Myself 29

Slide 93

Slide 93 text

Resources Alex Lockwood https://github.com/alexjlockwood/bees-and-bombs-compose https://github.com/alexjlockwood/android-2048-compose Joe Birch https://joebirch.co/exploring-jetpack-compose/ Gurupreet Singh https://github.com/Gurupreet/ComposeCookBook Leland Richardson https://www.twitch.tv/intelligibabble Official by Google https://developer.android.com/courses/pathways/compose Vinay Gaba https://github.com/vinaygaba/Learn-Jetpack-Compose-By-Example 30

Slide 94

Slide 94 text

Thank You for Listening! Code is available at https://github.com/wajahatkarim3/droidcon2020 WajahatKarim wajahatkarim.com/subscribe wajahatkarim.com 31