Skip to content

MotionEffect

Nicolas Roard edited this page Mar 11, 2021 · 17 revisions

MotionEffect

MotionEffect is a new motion helper in 2.1 let you automatically add keyframes to the views it references, depending on their overall movement direction. It can simplifies a lot creating well crafted transitions.

To better understand where this is useful, take the following example:

The default transition between the two states do a linear interpolation -- the result is confusing and not pleasant.

If we look at this example, we can identify elements that are moving west only (2, 3, 6, 9), and others moving in a different pattern (1, 4, 5, 7, 8):

We can use MotionEffect to apply a fade effect to those elements, giving a much more pleasant result:

You can look at this example to see it in action:

<androidx.constraintlayout.motion.widget.MotionLayout ... >
    <TextView android:id="@+id/t1" ... />
    <TextView android:id="@+id/t2" ... />
    <TextView android:id="@+id/t3" ... />
    <TextView android:id="@+id/t4" ... />
    <TextView android:id="@+id/t5" ... />
    <TextView android:id="@+id/t6" ... />
    <TextView android:id="@+id/t7" ... />
    <TextView android:id="@+id/t8" ... />
    <TextView android:id="@+id/t9" ... />
   
    ...
  
    <androidx.constraintlayout.helper.widget.MotionEffect
        android:id="@+id/fade"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:constraint_referenced_ids="t1,t2,t3,t4,t5,t6,t7,t8,t9"
    />
</androidx.constraintlayout.motion.widget.MotionLayout>    

Controling which views get the effect

First, only the views referenced in the MotionEffect will possibly get the effect applied to them.

Secondly, by default, we automatically compute the main direction of movement of those views (between North, South, East, West), and only the views that are moving opposite to that direction will get the effect applied to them.

Using motionEffect_move=auto|north|south|east|west you can override this to specify which direction you want the effect to apply to.

You can also make this apply strictly (or not) to elements doing this motion with motionEffect_strict=true|false.

Default effect

By default the effect will apply a fade out / fade in; you can control the amount of alpha as well as the start/end of the effect with the following attributes:

app:motionEffect_start="keyframe"
app:motionEffect_end="keyframe"       

You can control the amount of alpha and translation in (x,y) to apply:

app:motionEffect_alpha="alpha"
app:motionEffect_translationX="dimension"
app:motionEffect_translationX="dimension"

Custom effect

You can also reference a View Transition to apply instead of the default fade effect, simply by setting motionEffect_viewTransition