This warehouse for Chinese translation warehouse, and added some of their own understanding. Git repository: github.com/lgvalle/Mat… Git repository address: github.com/woolsen/Mat…

No maintainance is intended.

The content is still valid as a reference but it won’t contain the latest new stuff

​ —- Luis G. Valle

No maintenance required. This content is still valid as a reference, but does not contain the latest content

The Android Transition Framework can be used in three main ways:

  1. Animation that sets the content of the Acitivity layout when jumping from one Activity to another Acitivity.
  2. When an Activity jumps, animate the shared elements between activities.
  3. Set the animation for View changes in the same Activity.

1. Transition between activities

Animate existing layout content

When jumping from Activity A to Activity B, the content layout sets the Transition animation based on the defined Transition. In android. The transition. The transition, there are three default transition animations can be used: explodes, Slide and Fade.

All of these transition animations track changes in the visibility of the target views in the active layout and animate those views to follow transition rules.

Explode Slide Fade

You can declare it in XML or write it in code. For example, a Fade can be declared as follows:

XML

The transition animation XML file is placed in res/ Transition

res/transition/activity_fade.xml


      
<fade xmlns:android="http://schemas.android.com/apk/res/"
    android:duration="1000"/>
Copy the code

res/transition/activity_slide.xml


      
<slide xmlns:android="http://schemas.android.com/apk/res/"
    android:duration="1000"/>

Copy the code

These transitions are then loaded using TransitionInflater

MainActivity.java

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_transition);
        setupWindowAnimations();
    }

    private void setupWindowAnimations(a) {
        Slide slide = TransitionInflater.from(this).inflateTransition(R.transition.activity_slide);
        getWindow().setExitTransition(slide);
    }
Copy the code

TransitionActivity.java

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_transition);
        setupWindowAnimations();
    }

    private void setupWindowAnimations(a) {
        Fade fade = TransitionInflater.from(this).inflateTransition(R.transition.activity_fade);
        getWindow().setEnterTransition(fade);
    }
Copy the code

Write in code

MainActivity.java

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_transition);
        setupWindowAnimations();
    }

    private void setupWindowAnimations(a) {
        Slide slide = new Slide();
        slide.setDuration(1000);
        getWindow().setExitTransition(slide);
    }
Copy the code

TransitionActivity.java

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_transition);
        setupWindowAnimations();
    }

    private void setupWindowAnimations(a) {
        Fade fade = new Fade();
        fade.setDuration(1000);
        getWindow().setEnterTransition(fade);
    }
Copy the code

Effect:

Step by step what happened:

  1. Activity A Starts Activity B

  2. The Transition Framework finds an Exit Transition (Slide) and applies it to all visible views.

  3. The Transition Framework finds the B Enter Transition (fade) and applies it to all visible views.

  4. When return is pressed, the Transition Framework executes a reverse animation of Enter and Exit, respectively (returnTransition and reenterTransition will be executed if we have defined them).

ReturnTransition and ReenterTransition

Return Transitions and Reenter Transitions are reverse animations of Enter and Exit, respectively.

  • EnterTransition <–> ReturnTransition
  • ExitTransition <–> ReenterTransition

If Return or Reenter is not defined, the system performs reverse Enter Transition and Exit Transition. However, if they are defined, different transformations can be used to enter and exit the Acitivity.

We can modify the previous Fade sample to define a ReturnTransition for the TransitionActivity. In the current example, a Slide transition animation is defined. At this point, when we return from B to A, what used to be A Fade Transition is now A Slide Transition

TransitionActivity.java

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_transition);
        setupWindowAnimations();
    }

    private void setupWindowAnimations(a) {
        Fade fade = new Fade();
        fade.setDuration(1000);
        getWindow().setEnterTransition(fade);
        
        Slide slide = new Slide();
        slide.setDuration(1000);
        getWindow().setReturnTransition(slide);        
    }
Copy the code

Note that if Return Transition is not defined, the reverse Enter Transition is performed. If a Return Transition is defined, the defined Return Transition is executed.

There is no Return the Transition A Return the Transition
Enter: Fade In Enter: Fade In
Exit: Fade Out Exit: Slide out

2. Shared elements between activities

This is mainly used for having two different attempts in two different layouts and somehow animating them together.

The Transition framework automatically animates scene transitions to show the user the Transition from one view to another.

Remember: Views don’t really move from one layout to another. They are two separate views that, through property Settings, create an effect for the View of the other layout that is identical to the View of the original layout, and then animate it.

A) Enable Window Content Transition

This needs to be set in styles.xml.

values/styles.xml

<style name="MaterialAnimations" parent="@style/Theme.AppCompat.Light.NoActionBar">.<item name="android:windowContentTransitions">true</item
    ...
</style>
Copy the code

You can also specify default Enter, exit, and transition animations for shared elements for your APP.

<style name="MaterialAnimations" parent="@style/Theme.AppCompat.Light.NoActionBar">.<! -- Specify enter and exit -->
    <item name="android:windowEnterTransition">@transition/explode</item>
    <item name="android:windowExitTransition">@transition/explode</item>

    <! -- Specify shared element transitions -->
    <item name="android:windowSharedElementEnterTransition">@transition/changebounds</item>
    <item name="android:windowSharedElementExitTransition">@transition/changebounds</item>.</style>
Copy the code

B) Define a transition name

To do this, you need to set the same Android :transitionName for the original View and the target View. They can have different ids and attributes, but Android :transitionName must be the same.

layout/activity_a.xml

<ImageView
        android:id="@+id/small_blue_icon"
        style="@style/MaterialAnimations.Icon.Small"
        android:src="@drawable/circle"
        android:transitionName="@string/blue_name" />
Copy the code

layout/activity_b.xml

<ImageView
        android:id="@+id/big_blue_icon"
        style="@style/MaterialAnimations.Icon.Big"
        android:src="@drawable/circle"
        android:transitionName="@string/blue_name" />
Copy the code

C) Start an Activity with shared elements

Using ActivityOptions. MakeSceneTransitionAnimation definition: Shared elements and the transition name () method.

MainActivity.java


blueIconImageView.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        Intent i = new Intent(MainActivity.this, SharedElementActivity.class);

        View sharedView = blueIconImageView;
        String transitionName = getString(R.string.blue_name);

        ActivityOptions transitionActivityOptions = ActivityOptions.makeSceneTransitionAnimation(MainActivity.this, sharedView, transitionName); startActivity(i, transitionActivityOptions.toBundle()); }});Copy the code

This code produces a nice transition animation:

As shown, the transition framework is creating and executing an animation that gives the illusion of the view moving from one Activity to another and changing shape.

Shared elements between fragments

The way shared element transition animations work in FramgNet is very similar to the way activities work.

A) and B) are exactly the same. Only C) needs to be modified

A) Enable Window Content Transition

values/styles.xml

<style name="MaterialAnimations" parent="@style/Theme.AppCompat.Light.NoActionBar">.<item name="android:windowContentTransitions">true</item>.</style>
Copy the code

B) Define a unified transition name

layout/fragment_a.xml

<ImageView
        android:id="@+id/small_blue_icon"
        style="@style/MaterialAnimations.Icon.Small"
        android:src="@drawable/circle"
        android:transitionName="@string/blue_name" />
Copy the code

layout/fragment_b.xml

<ImageView
        android:id="@+id/big_blue_icon"
        style="@style/MaterialAnimations.Icon.Big"
        android:src="@drawable/circle"
        android:transitionName="@string/blue_name" />
Copy the code

C) Open a fragment with shared elements

To do this, you need to set the shared element transformation information as part of the FragmentTransaction process.

FragmentB fragmentB = FragmentB.newInstance(sample);

// Define the Enter transition for all views of the fragment
Slide slideTransition = new Slide(Gravity.RIGHT);
slideTransition.setDuration(1000);
sharedElementFragment2.setEnterTransition(slideTransition);

// Define enter Transition for shared elements only
ChangeBounds changeBoundsTransition = TransitionInflater.from(this).inflateTransition(R.transition.change_bounds);
fragmentB.setSharedElementEnterTransition(changeBoundsTransition);

getFragmentManager().beginTransaction()
        .replace(R.id.content, fragmentB)
        .addSharedElement(blueView, getString(R.string.blue_name))
        .commit();
Copy the code

This is the final result:

Allow transition overlap

You can define whether the entry and exit transition animations can overlap.

The Android documentation:

When true, Enter Transition begins immediately.

When false, Enter Transition waits for exit transition to finish before starting.

This setting works for both Fragment and Activitiy’s shared element transition animations.

FragmentB fragmentB = FragmentB.newInstance(sample);

// Define the Enter transition for all views of the fragment
Slide slideTransition = new Slide(Gravity.RIGHT);
slideTransition.setDuration(1000);
sharedElementFragment2.setEnterTransition(slideTransition);

// Define enter Transition for shared elements only
ChangeBounds changeBoundsTransition = TransitionInflater.from(this).inflateTransition(R.transition.change_bounds);
fragmentB.setSharedElementEnterTransition(changeBoundsTransition);

// Prevent overlapping transitions
fragmentB.setAllowEnterTransitionOverlap(overlap);
fragmentB.setAllowReturnTransitionOverlap(overlap);

getFragmentManager().beginTransaction()
        .replace(R.id.content, fragmentB)
        .addSharedElement(blueView, getString(R.string.blue_name))
        .commit();
Copy the code

You can easily see the difference in the following example:

Overlap True Overlap False
Fragment_2 appears at the top of Fragment_1 Fragment_2 Waits for Fragment_1 to disappear

3. Animate the view layout elements

Scenes

The Transition Framework can also be used to animate changes to elements in the current Activity layout

Transition animations occur between scenes. A Scene is just a regular layout that defines the static state of the UI. You can go from one scene to another, and the Transition Framework will animate between the two scenes.

scene1 = Scene.getSceneForLayout(sceneRoot, R.layout.activity_animations_scene1, this);
scene2 = Scene.getSceneForLayout(sceneRoot, R.layout.activity_animations_scene2, this);
scene3 = Scene.getSceneForLayout(sceneRoot, R.layout.activity_animations_scene3, this);
scene4 = Scene.getSceneForLayout(sceneRoot, R.layout.activity_animations_scene4, this); (...).@Override
public void onClick(View v) {
    switch (v.getId()) {
        case R.id.button1:
            TransitionManager.go(scene1, new ChangeBounds());
            break;
        case R.id.button2:
            TransitionManager.go(scene2, TransitionInflater.from(this).inflateTransition(R.transition.slide_and_changebounds));
            break;
        case R.id.button3:
            TransitionManager.go(scene3, TransitionInflater.from(this).inflateTransition(R.transition.slide_and_changebounds_sequential));
            break;
        case R.id.button4:
            TransitionManager.go(scene4, TransitionInflater.from(this).inflateTransition(R.transition.slide_and_changebounds_sequential_with_interpolators));
            break; }}Copy the code

This code uses transition animations between four scenes in the same Activity. Each transition defines a different animation.

The transition framework takes all the visible views in the current scene and arranges them based on the animation needed to calculate the next scene.

Layout changes

The Transition Framework can also be used to animate layout property changes in a view. You just need to make any changes you want and it will perform the necessary animations for you.

A) Start to delay the transition

With this line of code, we tell the framework that we are going to make some UI changes that will need to be animated.

TransitionManager.beginDelayedTransition(sceneRoot);
Copy the code

B) Change view layout properties

ViewGroup.LayoutParams params = greenIconView.getLayoutParams();
params.width = 200;
greenIconView.setLayoutParams(params);
Copy the code

Changing view width attribute to make it smaller will trigger a layoutMeasure. At that point the Transition framework will record start and ending values and will create an animation to transition from one to another.

4. (extra) Shared elements + Circular Reveal

Circular Reveal is an animation used to show and hide a set of UI elements with a visual effect similar to ripples. It is available in the ViewAnimationUtils class from API 21.

Circular Reveal animations can be combined with shared element transformations to create meaningful animations that smoothly show the user what’s going on.

What happens progressively in this example is:

  • The orange circle is a shared element fromMainActivityThe transition toRevealActivity.
  • inRevealActivityOn, a listener listens for the completion of the shared element conversion. When this happens, it does two things:
    • Execute Circular Reveal animation for the Toolbar
    • Use regularViewPropertyAnimatorinRevealActivityPerform the zoom animation on the view

Listen for the shared element Enter transition to end

Transition transition = TransitionInflater.from(this).inflateTransition(R.transition.changebounds_with_arcmotion);
getWindow().setSharedElementEnterTransition(transition);
transition.addListener(new Transition.TransitionListener() {
    @Override
    public void onTransitionEnd(Transition transition) { animateRevealShow(toolbar); animateButtonsIn(); } (...). });Copy the code

Reveal Toolbar

private void animateRevealShow(View viewRoot) {
    int cx = (viewRoot.getLeft() + viewRoot.getRight()) / 2;
    int cy = (viewRoot.getTop() + viewRoot.getBottom()) / 2;
    int finalRadius = Math.max(viewRoot.getWidth(), viewRoot.getHeight());

    Animator anim = ViewAnimationUtils.createCircularReveal(viewRoot, cx, cy, 0, finalRadius);
    viewRoot.setVisibility(View.VISIBLE);
    anim.setDuration(1000);
    anim.setInterpolator(new AccelerateInterpolator());
    anim.start();
}
Copy the code

Zoom in on the View in the activity layout

private void animateButtonsIn(a) {
    for (int i = 0; i < bgViewGroup.getChildCount(); i++) {
        View child = bgViewGroup.getChildAt(i);
        child.animate()
                .setStartDelay(100 + i * DELAY)
                .setInterpolator(interpolator)
                .alpha(1)
                .scaleX(1)
                .scaleY(1); }}Copy the code

More Circular Reveal animations

There are many different ways to create display animations. It is important to use animation to help the user understand what is happening in the application.

Display Circular Reveal from the middle of the target view

int cx = (viewRoot.getLeft() + viewRoot.getRight()) / 2;
int cy = viewRoot.getTop();
int finalRadius = Math.max(viewRoot.getWidth(), viewRoot.getHeight());

Animator anim = ViewAnimationUtils.createCircularReveal(viewRoot, cx, cy, 0, finalRadius);
viewRoot.setBackgroundColor(color);
anim.start();
Copy the code

Display Circular Reveal + animation from the top of the target view

int cx = (viewRoot.getLeft() + viewRoot.getRight()) / 2;
int cy = (viewRoot.getTop() + viewRoot.getBottom()) / 2;
int finalRadius = Math.max(viewRoot.getWidth(), viewRoot.getHeight());

Animator anim = ViewAnimationUtils.createCircularReveal(viewRoot, cx, cy, 0, finalRadius);
viewRoot.setBackgroundColor(color);
anim.addListener(new AnimatorListenerAdapter() {
    @Override
    public void onAnimationEnd(Animator animation) { animateButtonsIn(); }}); anim.start();Copy the code

Display Circular Reveal from the touch point

@Override
public boolean onTouch(View view, MotionEvent motionEvent) {
    if (motionEvent.getAction() == MotionEvent.ACTION_DOWN) {
        if(view.getId() == R.id.square_yellow) { revealFromCoordinates(motionEvent.getRawX(), motionEvent.getRawY()); }}return false;
}
Copy the code
private Animator animateRevealColorFromCoordinates(int x, int y) {
    float finalRadius = (float) Math.hypot(viewRoot.getWidth(), viewRoot.getHeight());

    Animator anim = ViewAnimationUtils.createCircularReveal(viewRoot, x, y, 0, finalRadius);
    viewRoot.setBackgroundColor(color);
    anim.start();
}
Copy the code

Animation and pass Reveal

Transition transition = TransitionInflater.from(this).inflateTransition(R.transition.changebounds_with_arcmotion);
transition.addListener(new Transition.TransitionListener() {
    @Override
    public void onTransitionEnd(Transition transition) { animateRevealColor(bgViewGroup, R.color.red); } (...). }); TransitionManager.beginDelayedTransition(bgViewGroup, transition); RelativeLayout.LayoutParams layoutParams =new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
layoutParams.addRule(RelativeLayout.CENTER_IN_PARENT);
btnRed.setLayoutParams(layoutParams);
Copy the code

The sample code

Original author’s address: github.com/lgvalle/Mat…

Chinese translation address: github.com/woolsen/Mat…

For more information

  • Alex Lockwood posts about Transition Framework. A great in deep into this topic: www.androiddesignpatterns.com/2014/12/act…
  • Amazing Repository with Lot of Material Design samples by Saul Molinero: github.com/saulmm/Andr…
  • Chet Hasse Video Explaining Transition Framework: www.youtube.com/watch?v=S3H…