NOTE: This slide contains animated GIFs which are not supported SpeakerDeck. You can watch the original animated version at http://slides.com/wajahatkarim/composeanimations
Are you excited about Jetpack Compose? Do you love playing & making games? Have you got that designer itch which makes you want to develop creative apps? Or you love the motion design and micro-interactions?
Although Jetpack Compose is a toolkit to create Android UI in a declarative form with the power of Kotlin language. But it can be used as a canvas for generative art, animations, or even games.
In this session, we'll take a look at the capabilities of Canvas API for Jetpack Compose and how can we implement different kinds of animations with it. We'll also dig into game development and discuss some common challenges like game loop, state management etc. We will also explore other UI animations and transitions with Jetpack Compose.
By the end of this talk, we'll be more familiar with the concepts of Canvas in Jetpack Compose and how we can use it during development to write animations or games.
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
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
Made with Jetpack Compose
Alex Lockwood Gurupreet Singh
3
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
AnimatedVisbility Composable
cs.android.com
AnimatedVisibility in LazyColumn
AnimatedVisibility in multiple Composables
11
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
@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
@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
@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
@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
@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
@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
@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
@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
Examples of animate()
By Gurupreet Singh
github.com/Gurupreet/ComposeCookBook
15
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
@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
@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
@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
@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
@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
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
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
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
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
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
Compose Canvas 101
DrawScope - Handles the drawing API
drawRect() drawOval() drawLine() drawImage()
drawRoundRect() drawCircle() drawArc() drawPath()
fun DrawScope.drawMyShape() { }
19
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
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
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
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
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
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
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
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
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
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
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
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
More Canvas Examples
Its all about mathematics & drawing
By Alex Lockwood
github.com/alexjlockwood/bees-and-bombs-compose/
github.com/wajahatkarim3/DinoCompose
22
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
Thank You for Listening!
Code is available at
https://github.com/wajahatkarim3/droidcon2020
WajahatKarim
wajahatkarim.com/subscribe
wajahatkarim.com
31