From Nothing to Material Transitions
Tags: technology, android
Published: 2021-07-01 11:36:54

---
title: From Nothing to Material Transitions
published: true
date: 2021-06-24 00:20:06 UTC
tags: Technology,android
canonical_url: https://victorbrandalise.com/from-nothing-to-material-transitions/
---

Animations rarely change the core functionally of an app but you can’t deny that they make a big difference for the user. When an app has great animations everything looks more fluid, it’s easier to understand how things fit together.

Transitions are used when you’re moving from one screen to another and you want to apply animations to one or multiple elements. In this article I’ll show you how to implement them in your app.

We’ll start with an app that has no animations and add the needed ones to improve it.

![](https://victorbrandalise.com/wp-content/uploads/2021/06/final_60d1255eb63fd300cbb7abd8_765063-1-min.gif)<figcaption>Without transitions / With transitions</figcaption>

## Preparation

Before we start, make sure you’re not using the wrong library version.

If you’re using `androidx.appcompat:appcompat:1.3.0` you’ll have to manually specify `androidx.fragment:fragment-ktx:1.3.5` because `appcompat:1.3.0` depends on `fragment:1.3.4` that introduced a bug related to fragment transitions.

![](https://victorbrandalise.com/wp-content/uploads/2021/06/image.png)<figcaption>See the “Bug Fixes” section</figcaption>

I was getting an `IndexOutOfBoundsException` exception when messing around with shared transitions and I took me a while to discover that the fragment library was the problem.

```
 java.lang.IndexOutOfBoundsException: Index: 5, Size: 5
        at java.util.ArrayList.get(ArrayList.java:437)
        at androidx.fragment.app.FragmentTransitionImpl.setNameOverridesReordered(FragmentTransitionImpl.java:183)
        at androidx.fragment.app.DefaultSpecialEffectsController.startTransitions(DefaultSpecialEffectsController.java:665)
```

Now let’s get started

## Basic Knowledge

If no return transition is set, the transition system will automatically reverse the enter transition when navigating back.

By default, transitions run on all child views within their scene root hierarchy. For example, if you have a _RecyclerView_, the animation will be applied to it and to its children. If that’s not the behavior you expect, set `android:transitionGroup="true"` on the view group to disable that. You can also apply it to the out most view in your layout to make the fragment animate as a whole.

If you have views that are populated after the fragment is created (a _RecyclerView_ for example) you need to tell the transition system to wait before starting the transitions. To do that you need to call `postponeEnterTransition` to postpone the transitions and call `startPostponedEnterTransition` when you’ve populated your views.

<script src="https://gist.github.com/victorbrndls/c8a3bc8b8da1f38822782014bfa05ea1.js"></script>
## Fade Through

We’ll start with one of the simplest transitions, **MaterialFadeThrough**. The fade through pattern is used for transitions between UI elements that do not have a strong relationship to each other.

![FadeThrough](https://victorbrandalise.com/wp-content/uploads/2021/06/final_60d12ab41d6d4a004e378ddc_10443-min.gif)<figcaption>FadeThrough</figcaption>

The transition here consists of going from the items fragment to the cart fragment. On the first fragment we define `exitTransition` and `reenterTransition` to `MaterialFadeThrough`.

<script src="https://gist.github.com/victorbrndls/5f67f15f5ea58ce63c474728c93c9714.js"></script>

On the destination fragment we define the same transition but on `enterTransition` and `returnTransition`.

<script src="https://gist.github.com/victorbrndls/cd8090ca267847bf562e885ee18bd080.js"></script>

If you’re using a _RecyclerView_ you might need to postpone the enter transition on the destination fragment. To learn how to do that, take a look at the **[Basic Knowledge](#basic-knowledge)** section.

This transition is a good option for **navigating between fragments** when you have a bottom navigation bar. The fade is subtle but adds a nice touch to the navigation.

> In a fade through transition, outgoing elements first fade out. Next, incoming elements fade in while scaling in overall size from 92% to 100%. The element scaling starts at 92%, rather than 0%, to avoid drawing excessive attention to the transition. The scale animation is applied only to incoming elements in order to emphasize new content over the old.
> 
> <cite><a href="https://material.io/design/motion/the-motion-system.html" target="_blank" rel="noreferrer noopener">The motion system</a></cite>

## Fade

The fade transition is usually used with dialogs, menus, or things that fit within the bounds of the existing screen.

![MaterialFade](https://victorbrandalise.com/wp-content/uploads/2021/06/final_60d27186e7b3ed006ef8aa02_718377-min.gif)<figcaption>MaterialFade</figcaption>

Implementing the `MaterialFade` transition is basically the same as implementing the `MaterialFadeThrough` transition, the only difference is the transition name.

<script src="https://gist.github.com/victorbrndls/4184500694a7417b7910829ebe480a9a.js"></script>

> When entering, elements use a fade and scale in overall size from 80% to 100%. The scale animation starts at 80%, rather than 0%, to avoid drawing excessive attention to the transition. When exiting, elements simply fade out. The scale animation is only applied to entering elements. This places emphasis on new content (entering elements) over old content (exiting elements).
> 
> <cite><a href="https://material.io/design/motion/the-motion-system.html" target="_blank" rel="noreferrer noopener">The motion system</a></cite>

### What’s the difference between Fade and Fade Through?

They look very similar but by looking at the specification we can see one main difference.

**Fade** – Scales from 80% to 100%  
**FadeThrough** – Scales from 92% to 100%

## Shared Axis

The `MaterialSharedAxis` transition is well suited for cases when you want to represent some kind of spatial relationship. Opening a search page would be good example, when the user searches something, the content below is expected to change.

![MaterialSharedAxis](https://victorbrandalise.com/wp-content/uploads/2021/06/final_60d275d41c0fef0036ea5a00_970787-min.gif)<figcaption>MaterialSharedAxis</figcaption>

For this transition to look good you need a pair of fragments to animate simultaneously. Their transitions will run together to create a directional animation.

You can control the transition direction by specifying the `forward` property on `MaterialSharedAxis`. In the forward direction, targets of the transition will scale out.

<script src="https://gist.github.com/victorbrndls/00dab3b51a88a122af2ad44586dc2cf6.js"></script>

On this example we’re using the Z axis but you should give the X and Y axis a try to see what they look like.

<script src="https://gist.github.com/victorbrndls/868e12499e83d3755617c497a0118089.js"></script>

For the transition to look great you need to specify the same `forward` value for `exitTransition` = `enterTransition` and `reenterTransition` = `returnTransition`.

## Container Transformation

This is the transition I love the most, `MaterialContainerTransform` is used as a shared element transition, that means it’s used to transition the view’s size, position, etc from the start state to the end state.

The Container Transformation is used a lot when you have a _RecyclerView_ that’s already displaying some portion of the content that’ll be available at another screen. By using this transition you can animate the change from one place to another.

![MaterialContainerTransform](https://victorbrandalise.com/wp-content/uploads/2021/06/final_60d3c8dea98a2c00c6549ff2_608871.gif)<figcaption>MaterialContainerTransform</figcaption>

First we need to specify a `transitionName` on the view we wish to transition. Transition names have to be unique, that’s why I’m adding `layoutPosition` to the end of the transition name. If you’re using a _RecyclerView_, you should do this when binding your _ViewHolder_.

<script src="https://gist.github.com/victorbrndls/82142aab69561ac4bd1b1ca5ff04114a.js"></script>

Now on the end layout file, add a `transitionName` to the view the animation will end on.

<script src="https://gist.github.com/victorbrndls/c356b3411809bf650dd7102613c66cc9.js"></script>

We want the transition to start when the item is clicked, on the item clicked handler we have to tell the transition system the views from the start state that will map to the end state. For example the `icon` that was clicked on the _RecyclerView_ will transition to the view on the end layout that has `R.string.item_detail_icon_transition_name` as `transitionName`. The `transitionName` you specified on the _ViewHolder_ is just used by android to keep track of things, you won’t use it anywhere else.

<script src="https://gist.github.com/victorbrndls/6c570e71d184dfd49237694e01cd9cee.js"></script>

Finally we specify the `MaterialContainerTransform` on the destination fragment. `drawingViewId` is the view that’ll be used as a plane for the animation, if you’re using Navigation specify your _NavController_ view.

<script src="https://gist.github.com/victorbrndls/3939508ddc292fdba03eb8c136fa277e.js"></script>

If you want your animation to follow an arced path, you also need to specify the path motion.

<script src="https://gist.github.com/victorbrndls/4559f382b0826db45d891031904c86e5.js"></script>

There are many ways to customize your transitions, you can learn more about them [here](https://material.io/design/motion/customization.html "https://material.io/design/motion/customization.html").

As I’ve said before, if you don’t specify a return transition, Android will automatically use the enter transition reversed.

Take a look at the last GIF again, the `MaterialContainerTransform` looks good but everything else uses a rough transition. Let’s learn how we can use many transitions together to achieve a better end result.

### Debug mode

In some cases you might need some help to understand what’s happening behind the transition and there’s a simple thing that can help you with that. `MaterialContainerTransform` has a `isDrawDebugEnabled` property that adds visual information to the transition.

<script src="https://gist.github.com/victorbrndls/a0b14992b7eaf5e7a937d34f4fa90d21.js"></script>

![MaterialContainerTransform](https://victorbrandalise.com/wp-content/uploads/2021/06/final_60d27b2136373500706b0161_424997-min.gif)<figcaption>MaterialContainerTransform </figcaption>

## Mixing transitions

We’ve learn learned about the 4 transitions provided by Material individually, now let me show you how I used 3 of them together to create an animation that is pleasing to the eyes.

First I started by using the `MaterialSharedAxis` transition on the list fragment, it works well because the views reduce size from 100% to 92%, that helps to focus on the icon animation.

<script src="https://gist.github.com/victorbrndls/6abac86d0cc13121aa39eaca30db38f2.js"></script>

Then I added the `MaterialFadeThrough` transition to the destination fragment but I excluded the icon from that animation because it’s already being animated by `MaterialContainerTransform`.

<script src="https://gist.github.com/victorbrndls/fac691f7ac55a9081c53285d8d133b1f.js"></script>

By doing just that the end result is much better

![Mixing transitions](https://victorbrandalise.com/wp-content/uploads/2021/06/final_60d3cb2e1be1440029f578d1_308606-min.gif)<figcaption>Mixing transitions</figcaption>

If you have any doubts you can find the [source code here](https://github.com/victorbrndls/BlogProjects/tree/material-transitions) or contact me.

The best way to learn is by doing, go and apply the knowledge you’ve acquired here to a concrete example. I’d enjoy seeing what you can accomplish. I hope this article was helpful for you.

## Resources

- [https://material.io/blog/android-material-motion](https://material.io/blog/android-material-motion)
- [https://blog.stylingandroid.com/category/animation/transition/](https://blog.stylingandroid.com/category/animation/transition/)
- [https://codelabs.developers.google.com/codelabs/material-motion-android](https://codelabs.developers.google.com/codelabs/material-motion-android)
- [https://material.io/design/motion/the-motion-system.html](https://material.io/design/motion/the-motion-system.html)

Photo by [Julian Hochgesang](https://unsplash.com/@julianhochgesang?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText) on [Unsplash](https://unsplash.com/s/photos/move?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText)

The post [From Nothing to Material Transitions](https://victorbrandalise.com/from-nothing-to-material-transitions/) first appeared on [Victor Brandalise](https://victorbrandalise.com).