Everybody is good! Here we go again… A few days do not see very miss!! Please forgive my laziness because I am busy recently!! There have been several articles written on MaterialDesign. Yesterday I came across a concept about excessive animation, so TODAY I want to share with you about the actual combat of excessive animation! Here nagging, many articles on the Internet are aimed at the animation of the page jump, in fact, the transition animation can not only realize the page jump, but also can take effect for some controls.

If you want to go straight to the case study, you can just start at # 3!!

Let’s take a quick look at the results:

This article focuses on the following aspects:

  • Introduction to transition animation:
  • Transition animation class introduction:
  • Button analysis of transition animation:

Introduction to excessive animation

The transition animation was introduced in Android5.0. It produces various animated effects by moving and switching elements between different states. At the beginning, there is no adaptation for the lower version, but github has made the corresponding adaptation address as follows. Later, the support package has added adaptation for the lower version, so pay attention to the use, otherwise there will be a warning.

The general inheritance relationship is as follows:

  • TransitionManager
  • Transition
    • Visibility
      • Explode
      • Slide
      • Fade
    • ChangeBounds
    • TransitionSet
    • TextScale
    • ChangeClipBounds
    • ChangeImageTransform
    • ChangeScroll
    • ChangeTransform

Introduction to the animation class:

1.TransitionManager transition animation management class

This animation management class mainly coordinates the corresponding animation management. There are several important apis:

  • TransitionManager.beginDelayedTransition(@NonNull final ViewGroup sceneRoot, @nullable Transition Transition) to Transition a root view
  • Transitionmanager.go (@nonnull Scene Scene, @nullable Transition Transition) Method of transitioning a view layer
  • TransitionManager. EndTransitions (final ViewGroup sceneRoot) end all the layout of the transition

1.1 TransitionManager. BeginDelayedTransition ()

This is mainly a transition method for root attempts: this is mainly dealing with transitions in a page! This method also has an overloaded method:

beginDelayedTransition(@NonNull final ViewGroup sceneRoot)
beginDelayedTransition(@NonNull final ViewGroup sceneRoot, @Nullable Transition transition)
Copy the code
  • Parameter 1: Root layout
  • Parameter 2: The corresponding transition animation type

There are several types of animation transitions:

  • AutoTransition is the default style
  • It fades in and out
  • Explode
  • Slide the mobile

The specific code is as follows:

        mCl_root = findViewById(R.id.cl_root);
        mTvText = findViewById(R.id.tv_text);
//        Slide slide = new Slide(Gravity.BOTTOM);
//        Explode explode = new Explode(); 
        Fade fade = new Fade();
        TransitionManager.beginDelayedTransition(mCl_root, fade);

        if (mTvText.getVisibility() == View.VISIBLE) {
            mTvText.setVisibility(View.GONE);
        } else {
            mTvText.setVisibility(View.VISIBLE);
        }
Copy the code

There will be three effects, here we suggest you set your own to see the effect!

If you want to set some other properties of the animation, you can do this:

fade.setDuration(300); / / set the animation time fade. SetInterpolator (new FastOutSlowInInterpolator ()); // Set the interpolator to fade. SetStartDelay (200); // Set the delayCopy the code

All of the above have these attributes!!

Note here that if you want to use zoom, color, and rotation changes, the adaptation library has them! The Transition class inherits and implements itself. Interested in children’s shoes can try…

1.2 TransitionManager. The go ()

To be honest, this thing I studied for a long time, various baidu to understand how to use, forgive me stupid… Let’s talk about my understanding of this thing! Transition from one layout file to another (note that this is a transition of layout files). I don’t know how to describe it…

Let’s look at the picture.

You all understand the picture above! In fact, it is the transition of two layout files, all transitions in the middle are wrapped by TransitionManager for us, you can choose the corresponding style to display! Let’s look at the specific code implementation!

This class is Scene. This class is described in the comments as a view hierarchy, which is equivalent to the layout file transitions mentioned above. In fact, this thing can be interpreted as layout.

Scene getSceneForLayout(@NonNull ViewGroup sceneRoot, @LayoutRes int layoutId, @NonNull Context context)
Copy the code
  • Parameter 1: Root layout (tag of the layout where the view level of the operation is located)
  • Parameter 2: Index of the view-level layout
  • Parameter 3: Root layout

Now you can create a corresponding view hierarchy! Here’s the code:

Because it is the transition of two layout files, so here we need a general layout, two layouts for switching, here you may not understand, soon you will understand!! Trust me, no you throw bugs at me;

  • Overall layout (root layout)
<? xml version="1.0" encoding="utf-8"? > <android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/cl_root"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.jinlong.newmaterialdesign.animation.TransitionManagerActivity">

    <android.support.v7.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="? attr/actionBarSize"
        android:background="@color/colorPrimaryDark"
        app:title="Show animation"
        app:titleTextColor="@android:color/white" />

    <Button
        android:id="@+id/btn_animation"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:onClick="animation"
        android:text="Animate transform"
        app:layout_constraintTop_toBottomOf="@id/toolbar" />

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:onClick="scene"
        android:text="Transform animation"
        app:layout_constraintLeft_toRightOf="@id/btn_animation"
        app:layout_constraintTop_toBottomOf="@id/toolbar" />

    <TextView
        android:id="@+id/tv_text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:padding="20dp"
        android:text="Please notice the changes in these words."
        app:layout_constraintTop_toBottomOf="@id/btn_animation" />

   <FrameLayout
       android:id="@+id/rl_root"
       android:layout_width="match_parent"
       app:layout_constraintTop_toBottomOf="@id/tv_text"
       android:layout_height="200dp">

       <include layout="@layout/scene1" />
   </FrameLayout>
</android.support.constraint.ConstraintLayout>
Copy the code

This is the layout file wrapped in FrameLayout. All based on here!!

  • Layout 1
<? xml version="1.0" encoding="utf-8"? > <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="200dp">

    <de.hdodenhof.circleimageview.CircleImageView
        android:id="@+id/civ_1"
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:layout_marginLeft="20dp"
        android:layout_marginTop="20dp"
        android:src="@mipmap/heard_1" />

    <de.hdodenhof.circleimageview.CircleImageView
        android:id="@+id/civ_2"
        android:layout_width="80dp"
        android:layout_height="80dp"
        android:layout_alignParentBottom="true"
        android:layout_alignParentRight="true"
        android:layout_marginBottom="20dp"
        android:layout_marginRight="20dp"
        android:src="@mipmap/heard_2" />

</RelativeLayout>
Copy the code
  • Layout 2
<? xml version="1.0" encoding="utf-8"? > <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="200dp">

    <de.hdodenhof.circleimageview.CircleImageView
        android:id="@+id/civ_2"
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:layout_marginLeft="20dp"
        android:layout_marginTop="20dp"
        android:src="@mipmap/heard_2" />

    <de.hdodenhof.circleimageview.CircleImageView
        android:id="@+id/civ_1"
        android:layout_width="80dp"
        android:layout_height="80dp"
        android:layout_alignParentBottom="true"
        android:layout_alignParentRight="true"
        android:layout_marginBottom="20dp"
        android:layout_marginRight="20dp"
        android:src="@mipmap/heard_1" />

</RelativeLayout>
Copy the code

The two layouts look like this. If you are careful, you may have noticed that the display form of the two layouts is the same, but the positions of the two controls have been switched. In fact, the expression of the animation is that the boy’s head moves from the top left corner to the bottom right corner, and the girl’s head moves from the bottom right corner to the top left corner. So at this point I think you will understand why I have been emphasizing the layout file is moved!

  • Code to initialize the view layer
    FrameLayout layout = findViewById(R.id.rl_root);
    mScene1 = Scene.getSceneForLayout(layout, R.layout.scene1, this);
    mScene2 = Scene.getSceneForLayout(layout, R.layout.scene2, this);
    TransitionManager.go(mScene1);
Copy the code

Two view layers are created here. To start, the default layer is displayed directly to View layer 1. Click the button to do the following:

TransitionManager.go(isScene2 ? mScene1 : mScene2,new ChangeBounds()); isScene2 = ! isScene2;Copy the code

This is done using a variable, if it shows view layer 2 then switch to layer 1, otherwise not! Can achieve the above effect!! The overall code is not posted, their own hands try, so remember firmly! And it’s not just limited to that. If there are three, you can also switch between creating three view layers. This you have to play the imagination space!

2. TransitionSet class is introduced

This class is simply a collection of animations that can be combined and displayed together.

    TransitionSet transitionSet = new TransitionSet();
    transitionSet.addTransition(slide);
    transitionSet.addTransition(fade);
Copy the code

This will directly add up the transitions above!

2.1 XML usage of TransitionSet

Here I feel it is necessary to explain the use of the following XML, first of all, to clarify where the layout should be placed res/transition/xxx.xml. Here’s the whole XML I’m going through:

<? xml version="1.0" encoding="utf-8"? > <transitionSet xmlns:android="http://schemas.android.com/apk/res/android"
    android:transitionOrdering="sequential"> <! Fade Android :duration="500">
        <targets>
            <target android:targetId="@id/toolBar"/>
            <target android:targetId="@android:id/statusBarBackground"/>
            <target android:targetId="@id/tv_show"/>
        </targets>
    </fade>
    
    <slide android:startDelay="600">
        <targets>
            <target android:targetId="@id/icon_sf"/>
        </targets>
    </slide>
    
    <slide android:startDelay="700">
        <targets>
            <target android:targetId="@id/icon_bh"/>
        </targets>
    </slide>

    <slide
        android:slideEdge="left"
        android:startDelay="500">
        <targets>
            <target android:targetId="@id/tv_show"/>
        </targets>
    </slide>
</transitionSet>
Copy the code
  • Android: transitionOrdering represent execution order
    • Sequential execution (what is written above is executed first)
    • Carry out together
  • Fade The fade attribute of the tag
  • The slide TAB moves the property
  • ChangeBounds label
    • The targets tag inside this is mainly to maintain the corresponding control needs to transition
      • Android: excludeId to remove the ID of the control without transition (generally used in the status bar, @ android: ID/statusBarBackground ID) of the status bar
  • Android :startDelay Delay time

There are basically only so many attributes you can use!! In fact, the manifest file mainly maintains which control needs which transition. That’s it!!

After talking so much, are you still confused? In fact, I also do not know how to express, so I am ready to use examples to explain, for their own memory and your understanding!!

3. Case analysis of transition animation:

Finally, I get to the point of this article. In fact, WHEN I first learned this thing, I was confused and didn’t understand it, but when I saw the code, IT was not so hard… Let’s start with the picture at the top of the home page.

3.1 Realization of top transition animation

The main thing to remember about the above animation effects is the concept of sharing. Why? Because the above animation is associated by share. The so-called rely on sharing, mainly this View transition to the next View corresponding presentation form! So there’s a problem, sharing you have to have two views have one View in common, and then there’s a common ID. How else will the next page know what you want to share with me? Let’s briefly define the Activity page (A) and Activity page (B).

  • A Page layout
<? xml version="1.0" encoding="utf-8"? > <android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/cl_root"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.jinlong.newmaterialdesign.animation.TransitionManagerActivity">

    <android.support.v7.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="? attr/actionBarSize"
        android:background="@color/colorPrimaryDark"
        app:title="Show animation"
        app:titleTextColor="@android:color/white" />

    <LinearLayout
        android:id="@+id/ll_shared"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_margin="20dp"
        android:onClick="sharedAnimation"
        android:orientation="horizontal"
        app:layout_constraintTop_toBottomOf="@id/toolbar">

        <de.hdodenhof.circleimageview.CircleImageView
            android:id="@+id/civ_heard"
            android:layout_width="50dp"
            android:layout_height="50dp"
            android:src="@mipmap/heard_1" />

        <TextView
            android:id="@+id/tv_title"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center_vertical"
            android:layout_marginLeft="30dp"
            android:text="This is a headline column." />
    </LinearLayout>
</android.support.constraint.ConstraintLayout>
Copy the code

Notice the CircleImageView control ID and TextView control ID, as mentioned above, will be used later!

  • The layout of page B looks like this
<? xml version="1.0" encoding="utf-8"? > <android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.jinlong.newmaterialdesign.animation.SharedActivity">


    <android.support.v7.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="? attr/actionBarSize"
        android:background="@color/colorPrimaryDark"
        app:title="Show animation"
        app:titleTextColor="@android:color/white" />


    <LinearLayout
        android:id="@+id/fl_top"
        android:layout_width="match_parent"
        android:layout_height="200dp"
        android:gravity="center"
        android:orientation="vertical"
        app:layout_constraintTop_toBottomOf="@id/toolbar">

        <de.hdodenhof.circleimageview.CircleImageView
            android:id="@+id/civ_heard"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:src="@mipmap/heard_1"
            android:transitionName="shared_image" />

        <TextView
            android:id="@+id/tv_title"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="20dp"
            android:text="That's the corresponding title."
            android:transitionName="shared_textview" />
    </LinearLayout>
</android.support.constraint.ConstraintLayout>
Copy the code

The ID here is the same as the ID up here. Also note the transitionName tag, which is used to set the shared content, and you’ll see why in a minute…

  • Jump through the code accordingly
        CircleImageView civHead = findViewById(R.id.civ_heard);
        TextView tvTitle = findViewById(R.id.tv_title);

        Intent intent = new Intent(this, SharedActivity.class);
        ActivityOptionsCompat optionsCompat = ActivityOptionsCompat.makeSceneTransitionAnimation(this,
                new Pair<View, String>(civHead, "shared_image"),
                new Pair<View, String>(tvTitle, "shared_textview"));
        startActivity(intent, optionsCompat.toBundle());
Copy the code

3.1.1 Method Description:

  • ActivityOptionsCompat makeSceneTransitionAnimation(Activity activity, Pair<View, String>… sharedElements)
  • ActivityOptionsCompat makeSceneTransitionAnimation(Activity activity, View sharedElement, String sharedElementName (String sharedElementName, String sharedElementName, String sharedElementName, String sharedElementName, String sharedElementName, String sharedElementName, String sharedElementName, String sharedElementName, String sharedElementName, String sharedElementName, String sharedElementName, String sharedElementName)
  • ActivityOptionsCompat makeCustomAnimation(Context context, int enterResId, Int exitResId), the effect of the overridePendingTransition before this is similar to the incoming parameters are basically the same
  • ActivityOptionsCompat makeScaleUpAnimation(View source, int startX, int startY, int startWidth, Int startHeight) from the page of the specific rectangle, start to zoom to the corresponding screen position, the above parameters, basically are related to the corresponding rectangle!
  • ActivityOptionsCompat makeThumbnailScaleUpAnimation(View source, Bitmap thumbnail, int startX, Int startY) thumbnail expands from the specified position to full screen. Should be good for picture display!

After reading the above content, I believe you can write the following animation effect!

3.2 Effect of diffusion circle in the back

The circular diffusion effect was not available until after 5.0 (using ViewAnimationUtils), so it must be tested on a 5.0 machine to use it. Otherwise it won’t work!! The code looks like this…

                    Animator circularReveal = ViewAnimationUtils.createCircularReveal(mImage_bg, 0, mImage_bg.getHeight(), 0, Math.max(mImage_bg.getHeight(), mImage_bg.getWidth()));
                    mImage_bg.setBackgroundColor(Color.BLACK);
                    circularReveal.setDuration(600);
                    circularReveal.start(); 
Copy the code

Animator createCircularReveal(View View, int centerX, int centerY, float startRadius, Float endRadius float endRadius float endRadius float endRadius You can try this in version 21!

3.3 Enter the animation Settings

In fact, the corresponding entry animation can be set on page B

  • getWindow().setEnterTransition(Transition transition); Set the animation for the entrance
  • getWindow().setReturnTransition(Transition transition); Set the animation for return
  • getWindow().setSharedElementEnterTransition(Transition transition); Set the animation to be shared upon entry
  • GetWindow (). SetSharedElementReturnTransition (Transition the Transition) returns are sharing the animation

One quick question is, how does Transition come from XML

TransitionInflater.from(this).inflateTransition(R.transition.return_slide)
Copy the code

Transition can be a concrete subclass or a manifest file. All that’s left is to let your imagination run wild! Post the rest of the code on the above page to end today’s content! If you are interested, please have a look at my project on GitHub!!


I wrote this article for several days, do not know how to write, feel a little disorderly, I hope you do not mind, what do not understand the message to me, I will timely reply…… Today is the day!