SlideShare a Scribd company logo
1 of 45
😸 Animations with Jetpack Compose
Antoine ROBIEZ
@enthuan
Baptiste CARLIER
@bapness
How to give life to your apps
Animate:
1. Give the appearance of movement using animation
techniques
2. Bring something to life
Jetpack Compose
• Declarative UI
• Kotlin
• Less code
• Compatible
Component = States
View = States
Screen = States
The purr-fect
Application
Jari Hytönen
Visibility Colors Rotation
Live coding
Visibility
AnimatedVisibility(fabExpand) {
Text(
modifier = Modifier.padding(horizontal = 8.dp),
text = "Trier"
)
}
Live coding results
val scaleY by animateFloatAsState(
targetValue = (if (sorted) {
-1f
} else {
1f
}),
animationSpec = tween(durationMillis = 500, easing = FastOutSlowInEasing)
)
Icon(
modifier = Modifier.scale(1f, scaleY),
imageVector = fabIcon,
contentDescription = null
)
Live coding results
AnimatedVisibility(
visible = expandState,
enter = slideInVertically(
initialOffsetY = { fullHeight -> fullHeight * -1 },
animationSpec = tween(durationMillis = 150, easing =
LinearOutSlowInEasing)
),
exit = slideOutVertically(
targetOffsetY = { fullHeight -> (fullHeight * -1) },
animationSpec = tween(durationMillis = 150, easing =
FastOutLinearInEasing)
)
) {
Text(
modifier = Modifier.padding(16.dp),
style = MaterialTheme.typography.bodyMedium,
text = cat.temper
)
}
Live coding results
• Use AnimatedVisibility(visible) to show/hide a
Composable
• Ability to customize enter / exit transitions
• Use AnimatedVisibilityScope with
Modifier.animateEnterExit(), you specify the child
element animation
Visibility
Visibility
Rotation
val arrowRotation by animateFloatAsState(
targetValue = (if (expandState) {
-180f
} else {
0f
}),
animationSpec = tween(durationMillis = 500, easing = FastOutSlowInEasing)
)
Icon(
modifier = Modifier
.padding(16.dp)
.rotate(arrowRotation)
,
imageVector = Icons.Filled.KeyboardArrowUp,
contentDescription = "Back"
)
Live coding results
Visibility
Rotation
Colors
val animationSpec = tween<Color>(400)
val contentColor = animateColorAsState(
targetValue = if (isFav) {
MaterialTheme.colorScheme.onPrimary
} else {
MaterialTheme.colorScheme.onSurface
},
animationSpec = animationSpec
)
val containerColor = animateColorAsState(
targetValue = if (isFav) {
MaterialTheme.colorScheme.primary
} else {
MaterialTheme.colorScheme.surface
},
animationSpec = animationSpec
)
Live coding results
Animate property from a State
• Use animate*AsState() APIs for value-based animation
• The animation is customizable with AnimationSpec
• Available animations:
animateDpAsState()
animateOffsetAsState()
animateFloatAsState()
animateColorAsState()
animateSizeAsState()
animateRectAsState()
animateIntAsState()
Interpolators
Linear Slow-In
Fast-Out
Slow-Out Slow-In-
Slow-Out
Live coding
Lists
Animated
Vector Drawable
ShapeShifter
https://shapeshifter.design/
var atEnd by remember { mutableStateOf(false) }
val fabIcon =
AnimatedImageVector.animatedVectorResource(R.drawable.avd_anim)
Icon(
painter = rememberAnimatedVectorPainter(fabIcon, atEnd),
contentDescription = null
)
Live coding results
Animated Vector Drawable
• Bound to a state (boolean)
• AnimatedImageVector:
✓ AnimatedImageVector.animatedVectorResource
• Painter:
✓ rememberAnimatedVectorPainter(vector, state)
• To trigger the animation, just reverse the state:
✓ state = !state
val onInverseSort = {
sorted = !sorted
coroutineScope.launch {
delay(200)
lazyListState.animateScrollToItem(0)
}
}
LazyColumn(
modifier = Modifier.fillMaxSize().padding(it),
state = lazyListState
) {
items(items = myItems, key = { it.id }) { cat ->
CatView(
modifier = Modifier
.fillMaxWidth()
.animateItemPlacement()
.clickable { onGoDetail(cat.id.toString()) }
.padding(horizontal = 24.dp, vertical = 16.dp),
cat = cat
)
}
}
Live coding results
• LazyItemScope:
✓ animateItemPlacement
• LazyListState:
✓ animateScrollToItem
✓ animateScrollBy
• Goodbye DiffUtils
Animate lists
Live coding
Transitions between screens
With a NavHost based navigation
Transitions
• AnimatedNavHost replaces NavHost
• Same mechanism than XML enter/exit/popEnter/popExit
• Not yet into Compose AndroidX
✓ Use Accompanist library
• Missing : SharedElement between screens
Navigation transitions
val onInverseSort = {
sorted = !sorted
coroutineScope.launch {
delay(200)
lazyListState.animateScrollToItem(0)
}
}
LazyColumn(
modifier = Modifier.fillMaxSize().padding(it),
state = lazyListState
) {
items(items = myItems, key = { it.id }) { cat ->
CatView(
modifier = Modifier
.fillMaxWidth()
.animateItemPlacement()
.clickable { onGoDetail(cat.id.toString()) }
.padding(horizontal = 24.dp, vertical = 16.dp),
cat = cat
)
}
}
Live coding results
Live coding
SplashScreen
Loading
Specifications, loops, transitions
AnimationSpecs allow to define how values should transform:
• tween: animates over the specified duration using an easing curve
• spring: a physics-based animation
• keyframes: based on the snapshot values specified at different timestamps
in the duration of the animation
• repeatable: repeat until it reaches the specified iteration count + a
animation (tween, spring, …)
• infiniteRepeatable: as repeatable, but indefinitely
• snap: immediately switches the value to the end value
Keyframes
val infiniteTransition = rememberInfiniteTransition()
val assRotation by infiniteTransition.animateFloat(
initialValue = -20f,
targetValue = -20f,
animationSpec = infiniteRepeatable(
animation = keyframes {
durationMillis = 1200
-20.0f at 0 with LinearOutSlowInEasing
20f at 600 with LinearOutSlowInEasing
-20f at 1200 with LinearOutSlowInEasing
},
repeatMode = RepeatMode.Restart
)
)
Box(modifier = modifier) {
Image(
painter = painterResource(id = R.drawable.cat_layer_back),
contentDescription = "Twerking cat",
modifier = Modifier.fillMaxSize()
.graphicsLayer {
rotationZ = assRotation
},
contentScale = ContentScale.Fit
)
Image(
painter = painterResource(id = R.drawable.cat_layer_front),
contentDescription = "",
modifier = Modifier.fillMaxSize(),
contentScale = ContentScale.Fit
)
}
Live coding results
Live coding
At launch
LaunchedEffect
val animatable = remember { Animatable(0f) }
LaunchedEffect(Unit) {
delay(800)
animatable.animateTo(targetValue = value, animationSpec = tween(2000))
}
Column(verticalArrangement = Arrangement.spacedBy(4.dp)) {
Text(
style = MaterialTheme.typography.bodyMedium,
fontWeight = FontWeight.SemiBold,
text = label
)
LinearProgressIndicator(
modifier = Modifier
.fillMaxWidth()
.height(8.dp)
.clip(RoundedCornerShape(4.dp)),
progress = animatable.value,
color = color,
trackColor = color.copy(alpha = 0.4f)
)
}
Live coding results
LaunchedEffect
• LaunchedEffect is triggered during the composition
• The animation runs even if the Composable isn’t displayed on
screen
• Be careful with LazyLayout items
➢ LaunchedEffect is called each time the view is displayed
It's easy
Set the right animation,
at the right time
Pay attention to physics
Animated Vector Drawable :
usable ?
useful ?
is it worth it ?
MotionLayout :
MotionLayout :
Animated Vector Drawable : is it worth it ?
usable ?
useful ?
Animated Vector Drawable :
MotionLayout : usable ?
useful ?
is it worth it ?
One screen =
Several components
Several views
Several states
Ask for animated mockups or wireframes
Android community needs you
your client needs you
your final user needs you
Just try it !
https://github.com/enthuan/compose-animations
Antoine ROBIEZ
@enthuan
Baptiste CARLIER
@bapness

More Related Content

Similar to Animations avec Compose : rendez vos apps chat-oyantes

Creating an Uber Clone - Part IV - Transcript.pdf
Creating an Uber Clone - Part IV - Transcript.pdfCreating an Uber Clone - Part IV - Transcript.pdf
Creating an Uber Clone - Part IV - Transcript.pdfShaiAlmog1
 
Introduction to Canvas - Toronto HTML5 User Group
Introduction to Canvas - Toronto HTML5 User GroupIntroduction to Canvas - Toronto HTML5 User Group
Introduction to Canvas - Toronto HTML5 User Groupdreambreeze
 
Introduction to Canvas - Toronto HTML5 User Group
Introduction to Canvas - Toronto HTML5 User GroupIntroduction to Canvas - Toronto HTML5 User Group
Introduction to Canvas - Toronto HTML5 User Groupbernice-chan
 
openFrameworks 007 - graphics
openFrameworks 007 - graphicsopenFrameworks 007 - graphics
openFrameworks 007 - graphicsroxlu
 
SwiftUI Animation - The basic overview
SwiftUI Animation - The basic overviewSwiftUI Animation - The basic overview
SwiftUI Animation - The basic overviewWannitaTolaema
 
Enhancing UI/UX using Java animations
Enhancing UI/UX using Java animationsEnhancing UI/UX using Java animations
Enhancing UI/UX using Java animationsNaman Dwivedi
 
Standford 2015 week4: 1.Protocols and Delegation, Gestures 2. Multiple MVCs
Standford 2015 week4: 1.Protocols and Delegation, Gestures 2. Multiple MVCsStandford 2015 week4: 1.Protocols and Delegation, Gestures 2. Multiple MVCs
Standford 2015 week4: 1.Protocols and Delegation, Gestures 2. Multiple MVCs彼得潘 Pan
 
Expand/Collapse animation on Android
Expand/Collapse animation on AndroidExpand/Collapse animation on Android
Expand/Collapse animation on AndroidPavlo Dudka
 
Fabric.js @ Falsy Values
Fabric.js @ Falsy ValuesFabric.js @ Falsy Values
Fabric.js @ Falsy ValuesJuriy Zaytsev
 
Model View Intent on Android
Model View Intent on AndroidModel View Intent on Android
Model View Intent on AndroidCody Engel
 
Animate The Web With Ember.js - Jessica Jordan
Animate The Web With Ember.js - Jessica JordanAnimate The Web With Ember.js - Jessica Jordan
Animate The Web With Ember.js - Jessica JordanJessica Jordan
 
Jetpack Compose - Hands-on February 2020
Jetpack Compose - Hands-on February 2020Jetpack Compose - Hands-on February 2020
Jetpack Compose - Hands-on February 2020Pedro Veloso
 
JavaFX 2.0 and Alternative Languages
JavaFX 2.0 and Alternative LanguagesJavaFX 2.0 and Alternative Languages
JavaFX 2.0 and Alternative LanguagesStephen Chin
 
How to Create Animation Using the AnimatedAlign Widget.pptx
How to Create Animation Using the AnimatedAlign Widget.pptxHow to Create Animation Using the AnimatedAlign Widget.pptx
How to Create Animation Using the AnimatedAlign Widget.pptxFlutter Agency
 
Kotlin Mullets
Kotlin MulletsKotlin Mullets
Kotlin MulletsJames Ward
 
Swift, via "swift-2048"
Swift, via "swift-2048"Swift, via "swift-2048"
Swift, via "swift-2048"Austin Zheng
 

Similar to Animations avec Compose : rendez vos apps chat-oyantes (20)

Intro to Canva
Intro to CanvaIntro to Canva
Intro to Canva
 
Creating an Uber Clone - Part IV - Transcript.pdf
Creating an Uber Clone - Part IV - Transcript.pdfCreating an Uber Clone - Part IV - Transcript.pdf
Creating an Uber Clone - Part IV - Transcript.pdf
 
Introduction to Canvas - Toronto HTML5 User Group
Introduction to Canvas - Toronto HTML5 User GroupIntroduction to Canvas - Toronto HTML5 User Group
Introduction to Canvas - Toronto HTML5 User Group
 
Introduction to Canvas - Toronto HTML5 User Group
Introduction to Canvas - Toronto HTML5 User GroupIntroduction to Canvas - Toronto HTML5 User Group
Introduction to Canvas - Toronto HTML5 User Group
 
openFrameworks 007 - graphics
openFrameworks 007 - graphicsopenFrameworks 007 - graphics
openFrameworks 007 - graphics
 
canvas_1.pptx
canvas_1.pptxcanvas_1.pptx
canvas_1.pptx
 
SwiftUI Animation - The basic overview
SwiftUI Animation - The basic overviewSwiftUI Animation - The basic overview
SwiftUI Animation - The basic overview
 
Enhancing UI/UX using Java animations
Enhancing UI/UX using Java animationsEnhancing UI/UX using Java animations
Enhancing UI/UX using Java animations
 
Standford 2015 week4: 1.Protocols and Delegation, Gestures 2. Multiple MVCs
Standford 2015 week4: 1.Protocols and Delegation, Gestures 2. Multiple MVCsStandford 2015 week4: 1.Protocols and Delegation, Gestures 2. Multiple MVCs
Standford 2015 week4: 1.Protocols and Delegation, Gestures 2. Multiple MVCs
 
Expand/Collapse animation on Android
Expand/Collapse animation on AndroidExpand/Collapse animation on Android
Expand/Collapse animation on Android
 
Fabric.js @ Falsy Values
Fabric.js @ Falsy ValuesFabric.js @ Falsy Values
Fabric.js @ Falsy Values
 
Model View Intent on Android
Model View Intent on AndroidModel View Intent on Android
Model View Intent on Android
 
Animate The Web With Ember.js - Jessica Jordan
Animate The Web With Ember.js - Jessica JordanAnimate The Web With Ember.js - Jessica Jordan
Animate The Web With Ember.js - Jessica Jordan
 
Jetpack Compose - Hands-on February 2020
Jetpack Compose - Hands-on February 2020Jetpack Compose - Hands-on February 2020
Jetpack Compose - Hands-on February 2020
 
JavaFX 2.0 and Alternative Languages
JavaFX 2.0 and Alternative LanguagesJavaFX 2.0 and Alternative Languages
JavaFX 2.0 and Alternative Languages
 
How to Create Animation Using the AnimatedAlign Widget.pptx
How to Create Animation Using the AnimatedAlign Widget.pptxHow to Create Animation Using the AnimatedAlign Widget.pptx
How to Create Animation Using the AnimatedAlign Widget.pptx
 
HTML5 Canvas
HTML5 CanvasHTML5 Canvas
HTML5 Canvas
 
Kotlin Mullets
Kotlin MulletsKotlin Mullets
Kotlin Mullets
 
Real life XNA
Real life XNAReal life XNA
Real life XNA
 
Swift, via "swift-2048"
Swift, via "swift-2048"Swift, via "swift-2048"
Swift, via "swift-2048"
 

Recently uploaded

The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxThe Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxLoriGlavin3
 
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxPasskey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxLoriGlavin3
 
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxA Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxLoriGlavin3
 
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...Alkin Tezuysal
 
Emixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native developmentEmixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native developmentPim van der Noll
 
Connecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdfConnecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdfNeo4j
 
Generative Artificial Intelligence: How generative AI works.pdf
Generative Artificial Intelligence: How generative AI works.pdfGenerative Artificial Intelligence: How generative AI works.pdf
Generative Artificial Intelligence: How generative AI works.pdfIngrid Airi González
 
Decarbonising Buildings: Making a net-zero built environment a reality
Decarbonising Buildings: Making a net-zero built environment a realityDecarbonising Buildings: Making a net-zero built environment a reality
Decarbonising Buildings: Making a net-zero built environment a realityIES VE
 
React Native vs Ionic - The Best Mobile App Framework
React Native vs Ionic - The Best Mobile App FrameworkReact Native vs Ionic - The Best Mobile App Framework
React Native vs Ionic - The Best Mobile App FrameworkPixlogix Infotech
 
Zeshan Sattar- Assessing the skill requirements and industry expectations for...
Zeshan Sattar- Assessing the skill requirements and industry expectations for...Zeshan Sattar- Assessing the skill requirements and industry expectations for...
Zeshan Sattar- Assessing the skill requirements and industry expectations for...itnewsafrica
 
Microservices, Docker deploy and Microservices source code in C#
Microservices, Docker deploy and Microservices source code in C#Microservices, Docker deploy and Microservices source code in C#
Microservices, Docker deploy and Microservices source code in C#Karmanjay Verma
 
Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...
Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...
Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...Nikki Chapple
 
QCon London: Mastering long-running processes in modern architectures
QCon London: Mastering long-running processes in modern architecturesQCon London: Mastering long-running processes in modern architectures
QCon London: Mastering long-running processes in modern architecturesBernd Ruecker
 
Bridging Between CAD & GIS: 6 Ways to Automate Your Data Integration
Bridging Between CAD & GIS:  6 Ways to Automate Your Data IntegrationBridging Between CAD & GIS:  6 Ways to Automate Your Data Integration
Bridging Between CAD & GIS: 6 Ways to Automate Your Data Integrationmarketing932765
 
Tampa BSides - The No BS SOC (slides from April 6, 2024 talk)
Tampa BSides - The No BS SOC (slides from April 6, 2024 talk)Tampa BSides - The No BS SOC (slides from April 6, 2024 talk)
Tampa BSides - The No BS SOC (slides from April 6, 2024 talk)Mark Simos
 
UiPath Community: Communication Mining from Zero to Hero
UiPath Community: Communication Mining from Zero to HeroUiPath Community: Communication Mining from Zero to Hero
UiPath Community: Communication Mining from Zero to HeroUiPathCommunity
 
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24Mark Goldstein
 
The State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxThe State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxLoriGlavin3
 
Potential of AI (Generative AI) in Business: Learnings and Insights
Potential of AI (Generative AI) in Business: Learnings and InsightsPotential of AI (Generative AI) in Business: Learnings and Insights
Potential of AI (Generative AI) in Business: Learnings and InsightsRavi Sanghani
 
[Webinar] SpiraTest - Setting New Standards in Quality Assurance
[Webinar] SpiraTest - Setting New Standards in Quality Assurance[Webinar] SpiraTest - Setting New Standards in Quality Assurance
[Webinar] SpiraTest - Setting New Standards in Quality AssuranceInflectra
 

Recently uploaded (20)

The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxThe Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
 
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxPasskey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
 
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxA Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
 
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
 
Emixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native developmentEmixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native development
 
Connecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdfConnecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdf
 
Generative Artificial Intelligence: How generative AI works.pdf
Generative Artificial Intelligence: How generative AI works.pdfGenerative Artificial Intelligence: How generative AI works.pdf
Generative Artificial Intelligence: How generative AI works.pdf
 
Decarbonising Buildings: Making a net-zero built environment a reality
Decarbonising Buildings: Making a net-zero built environment a realityDecarbonising Buildings: Making a net-zero built environment a reality
Decarbonising Buildings: Making a net-zero built environment a reality
 
React Native vs Ionic - The Best Mobile App Framework
React Native vs Ionic - The Best Mobile App FrameworkReact Native vs Ionic - The Best Mobile App Framework
React Native vs Ionic - The Best Mobile App Framework
 
Zeshan Sattar- Assessing the skill requirements and industry expectations for...
Zeshan Sattar- Assessing the skill requirements and industry expectations for...Zeshan Sattar- Assessing the skill requirements and industry expectations for...
Zeshan Sattar- Assessing the skill requirements and industry expectations for...
 
Microservices, Docker deploy and Microservices source code in C#
Microservices, Docker deploy and Microservices source code in C#Microservices, Docker deploy and Microservices source code in C#
Microservices, Docker deploy and Microservices source code in C#
 
Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...
Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...
Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...
 
QCon London: Mastering long-running processes in modern architectures
QCon London: Mastering long-running processes in modern architecturesQCon London: Mastering long-running processes in modern architectures
QCon London: Mastering long-running processes in modern architectures
 
Bridging Between CAD & GIS: 6 Ways to Automate Your Data Integration
Bridging Between CAD & GIS:  6 Ways to Automate Your Data IntegrationBridging Between CAD & GIS:  6 Ways to Automate Your Data Integration
Bridging Between CAD & GIS: 6 Ways to Automate Your Data Integration
 
Tampa BSides - The No BS SOC (slides from April 6, 2024 talk)
Tampa BSides - The No BS SOC (slides from April 6, 2024 talk)Tampa BSides - The No BS SOC (slides from April 6, 2024 talk)
Tampa BSides - The No BS SOC (slides from April 6, 2024 talk)
 
UiPath Community: Communication Mining from Zero to Hero
UiPath Community: Communication Mining from Zero to HeroUiPath Community: Communication Mining from Zero to Hero
UiPath Community: Communication Mining from Zero to Hero
 
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
 
The State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxThe State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptx
 
Potential of AI (Generative AI) in Business: Learnings and Insights
Potential of AI (Generative AI) in Business: Learnings and InsightsPotential of AI (Generative AI) in Business: Learnings and Insights
Potential of AI (Generative AI) in Business: Learnings and Insights
 
[Webinar] SpiraTest - Setting New Standards in Quality Assurance
[Webinar] SpiraTest - Setting New Standards in Quality Assurance[Webinar] SpiraTest - Setting New Standards in Quality Assurance
[Webinar] SpiraTest - Setting New Standards in Quality Assurance
 

Animations avec Compose : rendez vos apps chat-oyantes

  • 1. 😸 Animations with Jetpack Compose Antoine ROBIEZ @enthuan Baptiste CARLIER @bapness How to give life to your apps
  • 2. Animate: 1. Give the appearance of movement using animation techniques 2. Bring something to life
  • 3. Jetpack Compose • Declarative UI • Kotlin • Less code • Compatible
  • 10. AnimatedVisibility(fabExpand) { Text( modifier = Modifier.padding(horizontal = 8.dp), text = "Trier" ) } Live coding results
  • 11. val scaleY by animateFloatAsState( targetValue = (if (sorted) { -1f } else { 1f }), animationSpec = tween(durationMillis = 500, easing = FastOutSlowInEasing) ) Icon( modifier = Modifier.scale(1f, scaleY), imageVector = fabIcon, contentDescription = null ) Live coding results
  • 12. AnimatedVisibility( visible = expandState, enter = slideInVertically( initialOffsetY = { fullHeight -> fullHeight * -1 }, animationSpec = tween(durationMillis = 150, easing = LinearOutSlowInEasing) ), exit = slideOutVertically( targetOffsetY = { fullHeight -> (fullHeight * -1) }, animationSpec = tween(durationMillis = 150, easing = FastOutLinearInEasing) ) ) { Text( modifier = Modifier.padding(16.dp), style = MaterialTheme.typography.bodyMedium, text = cat.temper ) } Live coding results
  • 13. • Use AnimatedVisibility(visible) to show/hide a Composable • Ability to customize enter / exit transitions • Use AnimatedVisibilityScope with Modifier.animateEnterExit(), you specify the child element animation Visibility
  • 15. val arrowRotation by animateFloatAsState( targetValue = (if (expandState) { -180f } else { 0f }), animationSpec = tween(durationMillis = 500, easing = FastOutSlowInEasing) ) Icon( modifier = Modifier .padding(16.dp) .rotate(arrowRotation) , imageVector = Icons.Filled.KeyboardArrowUp, contentDescription = "Back" ) Live coding results
  • 17. val animationSpec = tween<Color>(400) val contentColor = animateColorAsState( targetValue = if (isFav) { MaterialTheme.colorScheme.onPrimary } else { MaterialTheme.colorScheme.onSurface }, animationSpec = animationSpec ) val containerColor = animateColorAsState( targetValue = if (isFav) { MaterialTheme.colorScheme.primary } else { MaterialTheme.colorScheme.surface }, animationSpec = animationSpec ) Live coding results
  • 18. Animate property from a State • Use animate*AsState() APIs for value-based animation • The animation is customizable with AnimationSpec • Available animations: animateDpAsState() animateOffsetAsState() animateFloatAsState() animateColorAsState() animateSizeAsState() animateRectAsState() animateIntAsState()
  • 22. var atEnd by remember { mutableStateOf(false) } val fabIcon = AnimatedImageVector.animatedVectorResource(R.drawable.avd_anim) Icon( painter = rememberAnimatedVectorPainter(fabIcon, atEnd), contentDescription = null ) Live coding results
  • 23. Animated Vector Drawable • Bound to a state (boolean) • AnimatedImageVector: ✓ AnimatedImageVector.animatedVectorResource • Painter: ✓ rememberAnimatedVectorPainter(vector, state) • To trigger the animation, just reverse the state: ✓ state = !state
  • 24. val onInverseSort = { sorted = !sorted coroutineScope.launch { delay(200) lazyListState.animateScrollToItem(0) } } LazyColumn( modifier = Modifier.fillMaxSize().padding(it), state = lazyListState ) { items(items = myItems, key = { it.id }) { cat -> CatView( modifier = Modifier .fillMaxWidth() .animateItemPlacement() .clickable { onGoDetail(cat.id.toString()) } .padding(horizontal = 24.dp, vertical = 16.dp), cat = cat ) } } Live coding results
  • 25. • LazyItemScope: ✓ animateItemPlacement • LazyListState: ✓ animateScrollToItem ✓ animateScrollBy • Goodbye DiffUtils Animate lists
  • 26. Live coding Transitions between screens With a NavHost based navigation
  • 28. • AnimatedNavHost replaces NavHost • Same mechanism than XML enter/exit/popEnter/popExit • Not yet into Compose AndroidX ✓ Use Accompanist library • Missing : SharedElement between screens Navigation transitions
  • 29. val onInverseSort = { sorted = !sorted coroutineScope.launch { delay(200) lazyListState.animateScrollToItem(0) } } LazyColumn( modifier = Modifier.fillMaxSize().padding(it), state = lazyListState ) { items(items = myItems, key = { it.id }) { cat -> CatView( modifier = Modifier .fillMaxWidth() .animateItemPlacement() .clickable { onGoDetail(cat.id.toString()) } .padding(horizontal = 24.dp, vertical = 16.dp), cat = cat ) } } Live coding results
  • 31.
  • 32. Specifications, loops, transitions AnimationSpecs allow to define how values should transform: • tween: animates over the specified duration using an easing curve • spring: a physics-based animation • keyframes: based on the snapshot values specified at different timestamps in the duration of the animation • repeatable: repeat until it reaches the specified iteration count + a animation (tween, spring, …) • infiniteRepeatable: as repeatable, but indefinitely • snap: immediately switches the value to the end value
  • 34. val infiniteTransition = rememberInfiniteTransition() val assRotation by infiniteTransition.animateFloat( initialValue = -20f, targetValue = -20f, animationSpec = infiniteRepeatable( animation = keyframes { durationMillis = 1200 -20.0f at 0 with LinearOutSlowInEasing 20f at 600 with LinearOutSlowInEasing -20f at 1200 with LinearOutSlowInEasing }, repeatMode = RepeatMode.Restart ) ) Box(modifier = modifier) { Image( painter = painterResource(id = R.drawable.cat_layer_back), contentDescription = "Twerking cat", modifier = Modifier.fillMaxSize() .graphicsLayer { rotationZ = assRotation }, contentScale = ContentScale.Fit ) Image( painter = painterResource(id = R.drawable.cat_layer_front), contentDescription = "", modifier = Modifier.fillMaxSize(), contentScale = ContentScale.Fit ) } Live coding results
  • 37. val animatable = remember { Animatable(0f) } LaunchedEffect(Unit) { delay(800) animatable.animateTo(targetValue = value, animationSpec = tween(2000)) } Column(verticalArrangement = Arrangement.spacedBy(4.dp)) { Text( style = MaterialTheme.typography.bodyMedium, fontWeight = FontWeight.SemiBold, text = label ) LinearProgressIndicator( modifier = Modifier .fillMaxWidth() .height(8.dp) .clip(RoundedCornerShape(4.dp)), progress = animatable.value, color = color, trackColor = color.copy(alpha = 0.4f) ) } Live coding results
  • 38. LaunchedEffect • LaunchedEffect is triggered during the composition • The animation runs even if the Composable isn’t displayed on screen • Be careful with LazyLayout items ➢ LaunchedEffect is called each time the view is displayed
  • 39. It's easy Set the right animation, at the right time Pay attention to physics
  • 40. Animated Vector Drawable : usable ? useful ? is it worth it ? MotionLayout :
  • 41. MotionLayout : Animated Vector Drawable : is it worth it ? usable ? useful ?
  • 42. Animated Vector Drawable : MotionLayout : usable ? useful ? is it worth it ?
  • 43. One screen = Several components Several views Several states Ask for animated mockups or wireframes
  • 44. Android community needs you your client needs you your final user needs you Just try it !

Editor's Notes

  1. ARO Concernant les animated vector drawable, c’est un peu étrange mais ça reste dans la logique compose. On doit avoir un état (eh oui encore) lié à l’animated Vector Drawable, récupérer la resource. Préparer un painter qui va bien sur etre remembered entre les compositions et le passer en attribut d’une image. Pour déclencher l’animation, on inversera simplement le booléen (au clic ou autre)