I want to change image in fab button during transition, but i haven't found how to do it with xml because CustomAttribute tag supports only drawable colors as values. My solution is to set TransitionAdapter to MotionLayout and change drawable in onTransitionChange function.
motionLayout.setTransitionListener(object : TransitionAdapter() {
var fromStart = true
var wasChanged = false
override fun onTransitionChange(
motionLayout: MotionLayout?,
startId: Int,
endId: Int,
progress: Float
) {
if (!wasChanged) {
if (fromStart && progress >= 0.5f) {
fab.setImageResource(R.drawable.ic_done_black_24dp)
wasChanged = true
}
if (!fromStart && progress <= 0.5f) {
fab.setImageResource(R.drawable.ic_add_black_24dp)
wasChanged = true
}
}
}
override fun onTransitionCompleted(motionLayout: MotionLayout?, currentId: Int) {
wasChanged = false
fromStart = !fromStart
}
})
But in this case image changes immediately. Is there any way to make the transition smooth like in regular transition in MotionLayout?
There is a great way to animate the change between two images in MotionLayout. However, it may be a little tricky with the Fab interaction. As shown in this blog post, you can use an ImageFilterView and set the source and alternate source, then crossfade between them. Grabbing code directly from the blog post linked above, here's an example of what an ImageFilterView looks like in your MotionLayout
<android.support.constraint.utils.ImageFilterView
android:id="@+id/image"
android:background="@color/colorAccent"
android:src="@drawable/roard"
app:altSrc="@drawable/hoford"
android:layout_width="64dp"
android:layout_height="64dp"/>
Where android:src
is your first image that you want and the app:altSrc
is the second image that you want to crossfade to.
Below, also grabbed directly from the blog post, is what the constraints will look like in your motionScene.
<ConstraintSet android:id="@+id/start">
<Constraint
android:id="@+id/image"
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_marginStart="8dp"
motion:layout_constraintBottom_toBottomOf="parent"
motion:layout_constraintStart_toStartOf="parent"
motion:layout_constraintTop_toTopOf="parent">
<CustomAttribute
motion:attributeName="crossfade"
motion:customFloatValue="0" />
</Constraint>
</ConstraintSet>
<ConstraintSet android:id="@+id/end">
<Constraint
android:id="@+id/image"
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_marginEnd="8dp"
motion:layout_constraintBottom_toBottomOf="parent"
motion:layout_constraintEnd_toEndOf="parent"
motion:layout_constraintTop_toTopOf="parent">
<CustomAttribute
motion:attributeName="crossfade"
motion:customFloatValue="1" />
</Constraint>
</ConstraintSet>
Where you set the crossfade value as a custom attribute. Not sure how this will play with the Fab but this is the best way I know how to animate between two images.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With