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:
- Animation that sets the content of the Acitivity layout when jumping from one Activity to another Acitivity.
- When an Activity jumps, animate the shared elements between activities.
- 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:
-
Activity A Starts Activity B
-
The Transition Framework finds an Exit Transition (Slide) and applies it to all visible views.
-
The Transition Framework finds the B Enter Transition (fade) and applies it to all visible views.
-
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 from
MainActivity
The transition toRevealActivity
. - in
RevealActivity
On, 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 regular
ViewPropertyAnimator
inRevealActivity
Perform 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…