Some time ago to do the picture viewer upgrade, when opening the picture viewer, can not find a good way to transition.

The doctor recommended the latest Material Motion animation of Android. Although our App was not arranged in the end, it provided an opportunity for me to learn Material Motion animation.

Recommended learning materials:

Official tutorial and project: “Material – Component-Android” Android official: “Using animation to start an Activity” my Demo: github.com/mCyp/Hoo

What is a transition animation?

When we study animation, we always hear about transition animation, so, what is transition animation?

First of all, for an animation, the two keyframes are the beginning frame and the end frame of the animation, and the transition is the transition between the two keyframes.

A complete transition animation is shown below:

Image from “Dynamic Design of transition mind method”

First, the initial transition

To teach you a dry thing:

adb shell settings put global window_animation_scale 10
adb shell settings put global transition_animation_scale 10
adb shell settings put global animator_duration_scale 10
Copy the code

This command slows the animation down 10 times to learn the details of the animation, and restores the speed from 10 to 1.

Remember how the first two activities transitioned? That’s right is to use the overridePendingTransition method.

The Android 2.0 later can use overridePendingTransition (int enterAnim, int exitAnim) to complete the Activity to jump animation, among them, The first parameter, exitAnim, corresponds to IN IN the transition of the image above, and the second parameter, enterAnim, corresponds to OUT IN the image above.

If you want to write a pan and transparency jump animation, it usually looks like this:

Step 1 Set the entry and exit animations

Create a new animation resource file in the anim directory under the resource file and enter the anim_in file:

<? The XML version = "1.0" encoding = "utf-8"? > <set xmlns:android="http://schemas.android.com/apk/res/android" android:duration="500"> <translate ToXDelta ="0" /> <alpha android:fromAlpha="0.0" Android :toAlpha="1.0" /> </set>Copy the code

Activity exits the anim_out file:

<? The XML version = "1.0" encoding = "utf-8"? > <set xmlns:android="http://schemas.android.com/apk/res/android" android:duration="500"> <translate ToXDelta ="-100%p" /> <alpha android:fromAlpha="1.0" Android :toAlpha="0.0" /> </set>Copy the code

Step 2 references the animation file

At the time of interface jump, call overridePendingTransition method:

companion object {
    fun start(context: Context){
        val intent = Intent(context, SecondActivity::class.java)
        context.startActivity(intent)
        if(context is Activity){
            context.overridePendingTransition(R.anim.anim_in, R.anim.anim_out)
        }
    }
}
Copy the code

Effect:

OverridePendingTransition writing problems

As with View animation, it is nice to use, but only supports four animation types: pan, rotate, zoom and transparency.

Android 5.0 Material Transition animation

After Android 5.0, we can use Material Design to bring us transitions.

Without saying anything else, let’s look at a few cases:

The official Demo The nuggets App My App

From left to right are the official Demo, the Gold Digging App, and my open source project Hoo. The differences from the original transition are as follows:

  1. If overridePendingTransition corresponds to View the animation, then the Material transitions correspond to the properties of animation, so you can customize interface transition animations.
  2. In addition to the entry and exit scenes, the Material transition adds a new scene for us, shared elements, which are used in the animation transitions of the above three images.
  3. It can be used not only for activities, but also between Fragments and views.

All three images use ImageView as A shared element (Hoo uses A more complex PhotoView), and the animation of the shared element is fun to watch, as images jump from screen A to screen B.

Why can I tell the Nuggets are also using Material transitions? Because the Material shared element animation starts with the StartView Alpha set to 0 by default, if you look closely at the opening of the large image, the image behind it is already missing, and there is a slight flaw in the initial transition.

1. Enter and exit the animation

Entry and exit animations do not include animations with shared elements, and only three animation types are supported:

animation explain
Explode(Explosive) Move the view into or out of the center of the scene
Slide(Sliding type) Move the view in or out of one of the edges of the scene
Fade(Fade in and out) Add or remove a view from a scene by changing its opacity

Careful students may find that Material Design does not support two types of animation, Scale and Rotation. Maybe these two types of transition animation are too few scenes. If you really want to use them, you can customize them.

Step 1 Create the Material Bundle

    startActivity(intent,
                  ActivityOptions.makeSceneTransitionAnimation(this).toBundle())
Copy the code

Step 2 Set the animation

override fun onCreate(savedInstanceState: Bundle?). {
    // Enable Material animation
    window.requestFeature(Window.FEATURE_ACTIVITY_TRANSITIONS)
    super.onCreate(savedInstanceState)
    //setContentView(R.layout.detail_activity)
    // Set the incoming animation
    window.enterTransition = Slide()
    // Set exit animation
    window.exitTransition = Slide()
}
Copy the code

In addition to this approach, you can also set the entry and exit animations by setting the theme, as well as shared animations.

2. Shared element animation

The steps to enable shared element animation are slightly different from the previous steps.

Step 1 Set Activity A

Set transitionName to View:

ivShoe.transitionName = transitionName
Copy the code

Next, it needs to provide the shared View and TransitionName.

Basically, you want to tell the system what View needs to be animated, and what if there are multiple views? Therefore, you should also bind the View to a TransitionName to prevent animation confusion.

Code:

val options = ActivityOptions.makeSceneTransitionAnimation(this, binding.ivShoe, transitionName)
ImageGalleryActivity.start(this, it, options.toBundle(), transitionName)
Copy the code

If you have multiple shared elements, you can put the relationship in the Pair, and then put the Pair in the Pair, and you can look at the Api if you don’t understand.

Step 2 sets the shared element animation for Activity B

Animation of shared elements is also limited by default, with the following types supported:

animation instructions
changeBounds Animates changes in the layout boundaries of the target view
changeClipBounds Animates changes in clipping boundaries for the target view
changeTransform Animates the zoom and rotation changes for the target view
changeImageTransform Animates changes in the size and scaling of the target image

Through setting sharedElementEnterTransition and sharedElementExitTransition Window:

override fun onCreate(savedInstanceState: Bundle?) {// Enable Material animation Window.requestFeature (window.feature_activity_transitions) val transitionSet = transitionSet () transitionSet.addTransition(ChangeBounds()) transitionSet.addTransition(ChangeClipBounds()) transitionSet.addTransition(ChangeImageTransform()) window.sharedElementEnterTransition = transitionSet Window. SharedElementExitTransition = transitionSet super. OnCreate (savedInstanceState) / / I am transitionName here is handed in by Intent Val transitionName = Intent.getStringExtra (CUS_TRANSITION_NAME) // Set ImageView transitionName binding.ivShoe.transitionName = transitionName }Copy the code

This works for most scenes, but if you are using Glide or another photo library to load your web image, chances are you will run into something like this:

Why does this happen? Since it takes time to load network pictures, we can wait for the pictures on page B to be loaded before we start animation. The Material installation factory supports such operations.

Calling the postponeEnterTransition() method in onCreate means that our animation needs to be delayed until we need it, Then call the Activity of startPostponedEnterTransition () method to start the animation, so, even in A interface, jump to B fragments in the interface, animation as well as can perform.

At this point, the interface can jump normally, the image is not put.

The principle of shared element animation is also very simple. If A jumps to B, the states of the shared elements of A and B will be recorded respectively, and then the state of the shared elements of B will be recorded, and the property animation will be performed according to the previously recorded states. Although it is called shared elements, they are different views.

Not only can activities support Material transitions, but fragments and Views are also available. If you are interested, you can do your own research.

Android Material Motion animation

What is the new Motion animation?

1. Introduction to Android Motion

In fact, it is the new support for four animation types, respectively:

1.1 the Container the transform

Container Transform is also an animation based on shared elements. The biggest difference is that its Start View can be either a ViewGroup or a View, as shown in Figure 1. Its Start View is a CardView.

1.2 Shared axis

The Shared axis looks like a pan animation, and the three examples shown are horizontal, vertical, and Z-axis.

1.3 Fade Through

Fade Through is essentially a transparency + zoom animation, and the official recommendation is to use it when jumping between two interfaces that are not closely related.

1.4 Fade

At first glance, the Fade animation is the same as the above Fade Through animation. In terms of the nature of animation, they are indeed the same transparency + zoom animation. However, it is officially suggested to consider this animation if it happens in the same interface, such as pop-up Dialog, Menu and other pop-ups.

Google provides two libraries for you to use.

One is the AndroidX package, which features:

  • Compatible with API 14
  • Only transitions between Fragments and Views are supported
  • Behavioral consistency

The other is the Platform package, which features:

  • Compatible with API 21
  • Supports fragments, Views, Activities, and Windows
  • On different apis, it might be a little different

The current App, the lowest version should be in 21, and support Activity, so it is suggested to choose Platform.

2. First experience of Material Motion

Let’s take the Container Transform as an example to experience the Android Motion animation between activities:

Step 1 introduces dependencies

implementation 'com. Google. Android. Material: material: 1.4.0 - alpha01'
Copy the code

Step 2 Set Activity A

Here the Activity A corresponds to the MainActivity, which enables the transition animation:

class MainActivity : AppCompatActivity() {

    / /...
    override fun onCreate(savedInstanceState: Bundle?). {
        window.requestFeature(Window.FEATURE_ACTIVITY_TRANSITIONS)
        setExitSharedElementCallback(MaterialContainerTransformSharedElementCallback())
        window.sharedElementsUseOverlay = false
        super.onCreate(savedInstanceState)
        / /...}}Copy the code

Step 3 Set the jump event

As with creating shared elements, set TransitionName first:

private fun onCreateListener(id: Long, url: String): View.OnClickListener {
    return View.OnClickListener {
        val transitionName = "${id}-${url}"
        it.transitionName = transitionName
        DetailActivity.start(context, id, it as ConstraintLayout, transitionName)
    }
}
Copy the code

This is done by placing the TransitionName setting in the click event, and then creating the Bundle:

const val CUS_TRANSITION_NAME: String = "transition_name"
class DetailActivity : AppCompatActivity() {
    companion object {
        fun start(context: Context, id: Long, viewGroup: ConstraintLayout, transitionName: String){
            val intent = Intent(context, DetailActivity::class.java)
            intent.putExtra(BaseConstant.DETAIL_SHOE_ID, id)
            intent.putExtra(CUS_TRANSITION_NAME, transitionName)
            if(context is Activity){
                context.startActivity(intent, ActivityOptions.makeSceneTransitionAnimation(context, viewGroup, transitionName).toBundle())
            }else {
                context.startActivity(intent)
            }
        }
    }
}
Copy the code

Step 4 Set Activity B

Demo of Activity B corresponds to the DetailActivity, this step is mainly for entry and exit share animation set MaterialContainerTransform, specific code is:

override fun onCreate(savedInstanceState: Bundle?). {
    // 1. Set the animation
    window.requestFeature(Window.FEATURE_ACTIVITY_TRANSITIONS)
    setEnterSharedElementCallback(MaterialContainerTransformSharedElementCallback())

    super.onCreate(savedInstanceState)
    / /...

    // 2. Set transitionName
    binding.mainContent.transitionName = intent.getStringExtra(CUS_TRANSITION_NAME)
    // 3. Set specific animations
    window.sharedElementEnterTransition = MaterialContainerTransform().apply {
        addTarget(binding.mainContent)
        duration = 300L
    }
    window.sharedElementExitTransition = MaterialContainerTransform().apply {
        addTarget(binding.mainContent)
        duration = 300L}}Copy the code

The Demo uses DataBinding, but all you need to know is that binding.mainContent is a ViewGroup. At this point, you should be able to see the Demo successfully.

Material Motion is similar to the Transition animations introduced in Android 5.0, but they make it a lot easier to use.

Four,

In the Android transition process:

  1. The initial View transition gave us support for four basic abilities: pan, scale, rotate, and transparency;
  2. Then, Android 5.0 Material transition brings us the surprise of shared element animation, and has the ability to customize transition animation, upgrade the gameplay of Android transition;
  3. Finally, Android Motion, which came out recently, makes transitions easier by encapsulating four types of animation.

Although the special scene of the starting picture viewer does not use Material transitions, the transition is still silky. If I am interested, I will write a separate article later.

Reference Address:

Official tutorial and project: “Material – Component-Android” Android official: “Use animation to start the Activity” Android advanced transition animation -ShareElement complete walkthrough “Dynamic design transition mind method”