The routine of this article is as follows. Let's pretend to take you flying.
- concept
- How to use it
- Set the same name
- Start Activity
- Fragment to Fragment
- Setting up multiple groups of elements
- Custom Overanimation
- Source Code Interpretation
- How to Compatible with Low Version
Let's see the effect first.
1. Concept
Before 5.0, the transition of different activities or segments was to enter and exit animation, and the view hierarchy was independent of each other.
Transition animation is: to connect the same elements of two activities to make a coherent animation; so as to achieve the elements between different views to achieve cool, explosive and other cool and elegant effects.
Guide user vision.
Shared element type:
explode: Move in or out of the center of the scene
slide: Move in or out of the edge of the scene
fade: adjusting transparency to produce a gradual effect
Animation effects:
ChangeeBounds - Change the layout boundaries of the target view
changeClipBounds - Clipping the target view boundary
ChangeeTransform - Change the zoom ratio and rotation angle of the target view
ChangeImage Transform - Changing the size and scale of the target image
2. How to use it
2.1 Setting Themes
Firstly, we need to set the theme in the system theme or in the java code to support transitional animation. We have transitional animation effect only when we switch pages. There are two ways to do this: one is to set the theme in the system theme, the other is to set the theme in the java code to support transitional animation.
2.1.1 Method 1
getWindow().requestFeature(Window.FEATURE_CONTENT_TRANSITIONS); // Set an exit transition getWindow().setExitTransition(new Explode());
Transition effects can be achieved when the total code settings are entered or exited by the following methods:
- Window.setEnterTransition(): Entry effect of ordinary transition
- Window.setExitTransition(): Exit effect of ordinary transition
- Window.setSharedElementEnterTransition(): Entry effect of shared element transition
- Window.setSharedElementExitTransition(): Exit effect of shared element transition
Method 2.1.2
Setting default configuration in xml
<!-- Base application theme. --> <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar"> <!-- Customize your theme here. --> <item name="android:windowContentTransitions">true</item> <!-- Designated Entry and Exit transitions --> <item name="android:windowEnterTransition">@transition/explode</item> <item name="android:windowExitTransition">@transition/explode</item> <!-- Appoint shared element transitions --> <item name="android:windowSharedElementEnterTransition"> @transition/change_image_transform</item> <item name="android:windowSharedElementExitTransition"> @transition/change_image_transform</item> ... </style>
2.2 Set the same name
To switch shared elements, first of all, make sure that the transitionName of the view in the two pages is identical.
Settings: android: transitionName
As follows:
MainActivity.xml
<android.support.v7.widget.CardView ...> <ImageView android:id="@+id/ivProfile" android:transitionName="profile" android:scaleType="centerCrop" android:layout_width="match_parent" android:layout_height="160dp" /> ... </android.support.v7.widget.CardView>
DetailActivity.xml
<LinearLayout ...> <ImageView android:id="@+id/ivProfile" android:transitionName="profile" android:scaleType="centerCrop" android:layout_width="match_parent" android:layout_height="380dp" /> ... </LinearLayout>
2.3 Start Activity
The first Acitivty to perform a page Jump requires the addition of Activity Options Compat. toBundle () to show the effect of transitional animation.
Intent intent = new Intent(this, DetailsActivity.class); // Pass data object in the bundle and populate details activity. intent.putExtra(DetailsActivity.EXTRA_CONTACT, contact); // getWindow().setExitTransition(new Explode()); //Setting Page Switching Effect //Used on first entry getWindow().setEnterTransition(new explode); //Used on reentry getWindow().setReenterTransition(new explode); Transition ts = new ChangeClipBounds(); //Setting Element Animation ts.setDuration(3000); getWindow().setSharedElementExitTransition(ts); ActivityOptionsCompat options = ActivityOptionsCompat. makeSceneTransitionAnimation(this, (View)ivProfile, "profile"); startActivity(intent, options.toBundle());
To convert the animation from the second Activity inversion scenario, call Activity. Support FinishAfterTransition () instead of Activity.finish (), and if you use toolbar's return button behavior, you also need to override it.
@Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { // Respond to the action bar's Up/Home button case android.R.id.home: supportFinishAfterTransition(); return true; } return super.onOptionsItemSelected(item); }
2.4 Fragment to Freagment
// Get access to or create instances to each fragment FirstFragment fragmentOne = ...; SecondFragment fragmentTwo = ...; // Check that the device is running lollipop if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { // Inflate transitions to apply Transition changeTransform = TransitionInflater.from(this). inflateTransition(R.transition.change_image_transform); Transition explodeTransform = TransitionInflater.from(this). inflateTransition(android.R.transition.explode); // Setup exit transition on first fragment fragmentOne.setSharedElementReturnTransition(changeTransform); fragmentOne.setExitTransition(explodeTransform); // Setup enter transition on second fragment fragmentTwo.setSharedElementEnterTransition(changeTransform); fragmentTwo.setEnterTransition(explodeTransform); // Find the shared element (in Fragment A) ImageView ivProfile = (ImageView) findViewById(R.id.ivProfile); // Add second fragment by replacing first FragmentTransaction ft = getFragmentManager().beginTransaction() .replace(R.id.container, fragmentTwo) .addToBackStack("transaction") .addSharedElement(ivProfile, "profile"); // Apply the transaction ft.commit(); } else { // Code to run on older devices }
2.6 Setting up multiple groups of elements
As you can see from the initial presentation, we can set the association of multiple groups of elements and perform different transitional animations for each element in the following ways:
Intent intent = new Intent(context, DetailsActivity.class); intent.putExtra(DetailsActivity.EXTRA_CONTACT, contact); Pair<View, String> p1 = Pair.create((View)ivProfile, "profile"); Pair<View, String> p2 = Pair.create(vPalette, "palette"); Pair<View, String> p3 = Pair.create((View)tvName, "text"); ActivityOptionsCompat options = ActivityOptionsCompat. makeSceneTransitionAnimation(this, p1, p2, p3); startActivity(intent, options.toBundle());
Note: android.util.Pair will be imported by default, but we will choose the android.support.v4.util.Pair class.
It is necessary to avoid distracting animation caused by too many elements, which may lose the significance of transitional animation.
3. Custom Overanimation
Essentially, it's about rewriting Transition.
The routine is as follows:
1. Inherit Visibility or Transition
2. Custom Animation: Implementing VIsibility/Transition Method
3. Set custom Transition in the page: getWindow().setEnterTransition or setSharedElementEnterTransition
Take a look at the effect of customization
3.1 Some concepts:
- Visibility extends Transition page switching transition animation class;
- PathMotion Class of shareView Moving Track Path
Example: https://github.com/LidongWen/LittlePrincess/blob/master/app/src/main/java/com/wenld/littleprincess/transition/ChangePosition.javaArcMotion arcMotion = new ArcMotion(); arcMotion.setMinimumHorizontalAngle(50f); arcMotion.setMinimumVerticalAngle(50f);
3.2 Custom Animation
Inherit Visibility:
Public void captureStartValues (Transition Values Transition Values) where an attribute value for calculating the initial state of an animation is saved Public void captureEndValues (Transition Values Transition Values) here holds an attribute value for calculating the end state of an animation public Animator onAppear(ViewGroup sceneRoot, final View view, TransitionValues startValues, TransitionValues endValues) This method is executed if a View is displayed when it enters the animation. public Animator onDisappear(ViewGroup sceneRoot, final View view, TransitionValues startValues, TransitionValues endValues) If it exits, VIew executes this method
Inherit Transition:
@Override public void captureStartValues(TransitionValues transitionValues) { //Initial value preservation } @Override public void captureEndValues(TransitionValues transitionValues) { //End Value Save } createAnimator(ViewGroup sceneRoot, TransitionValues startValues, TransitionValues endValues){ //Create execution animation }
3.3 Call
getWindow().setEnterTransition(new CommentEnterTransition(this, toolbar, bottom_aty_love));//Set up getWindow().setSharedElementEnterTransition(buildShareElemEnterSet());//Set up Enter Conversion Animation getWindow().setSharedElementReturnTransition(buildShareElemReturnSet());//Setting Exit Conversion Animation
Activeness for custom transition animation: https://github.com/LidongWen/LittlePrincess/blob/master/app/src/main/java/com/wenld/littleprincess/activity/LoveActivity.java
4. Source Code Interpretation
With a few questions:
- Where is the method called in Transition
-
Look at the transformation class notation of a system. Select Explode here.
-
Called within TransitionKitKat
@Override public void captureEndValues(TransitionValues transitionValues) { android.transition.TransitionValues internalValues = new android.transition.TransitionValues(); copyValues(transitionValues, internalValues); mTransition.captureEndValues(internalValues); copyValues(internalValues, transitionValues); } @Override public void captureStartValues(TransitionValues transitionValues) { android.transition.TransitionValues internalValues = new android.transition.TransitionValues(); copyValues(transitionValues, internalValues); mTransition.captureStartValues(internalValues); copyValues(internalValues, transitionValues); } @Override public Animator createAnimator(ViewGroup sceneRoot, TransitionValues startValues, TransitionValues endValues) { android.transition.TransitionValues internalStartValues; android.transition.TransitionValues internalEndValues; if (startValues != null) { internalStartValues = new android.transition.TransitionValues(); copyValues(startValues, internalStartValues); } else { internalStartValues = null; } if (endValues != null) { internalEndValues = new android.transition.TransitionValues(); copyValues(endValues, internalEndValues); } else { internalEndValues = null; } return mTransition.createAnimator(sceneRoot, internalStartValues, internalEndValues); }
Explode source code
- Explode is structured as follows:
public class Explode extends Visibility { public Explode() { setPropagation(new CircularPropagation()); } private void captureValues(TransitionValues transitionValues) { } //initial value @Override public void captureStartValues(TransitionValues transitionValues) { super.captureStartValues(transitionValues); captureValues(transitionValues); } //End value @Override public void captureEndValues(TransitionValues transitionValues) { super.captureEndValues(transitionValues); captureValues(transitionValues); } // Called upon entry @Override public Animator onAppear(ViewGroup sceneRoot, View view, TransitionValues startValues, TransitionValues endValues) { //Execute animation return TranslationAnimationCreator.createAnimation(view, endValues, bounds.left, bounds.top, startX, startY, endX, endY, sDecelerate, this); } //Called when exiting the page @Override public Animator onDisappear(ViewGroup sceneRoot, View view, TransitionValues startValues, TransitionValues endValues) { return TranslationAnimationCreator.createAnimation(view, startValues, viewPosX, viewPosY, startX, startY, endX, endY, sAccelerate, this); } private void calculateOut(View sceneRoot, Rect bounds, int[] outVector) { } }
It's too simple to call TranslationAnimation Creator. CreateAnimation to create animation.... Our custom transition animation above is learned from this product.
5. Compatible with Low Version
Here's a song for you: Feel your body hollowed out...
Because of complexity,
Low version compatibility is still the way to go, there will be time or clear needs to achieve it in the future:
Ideas:
- Take out the shared element View from the first page to set it in window s.
- The second page saves the data of the first page sharing element, and unifies the data of the shared element in the second interface to set up the entry animation and exit animation.
- Enter animation execution;
4. Execute Exit Animation
- Enter animation execution;
Material Design Element Conversion Animation Compatible with Low Version (Maybe not!)
Reference resources:
- https://github.com/codepath/android_guides/wiki/Shared-Element-Activity-Transition
- http://www.bkjia.com/Androidjc/900882.html
- http://www.jianshu.com/p/37e94f8b6f59
- http://www.jianshu.com/p/cc6cb29ec298
- http://www.open-open.com/lib/view/open1477879867267.html
demo address: Poke me!!!
I hope my article will not mislead you in watching, if there is any objection, welcome to discuss and correct.
If it can bring you something to watch, that's the best.