Objective
Before Android 5.0, we had a overridePendingTransition()
way to achieve some transitions. However, after Android 5.0, the transitions are more cool.
For example, the following animation:
A, Android L in the transition animation
It takes only three steps to implement a transitions animation:
Create a transition folder under the Res/directory that defines the animation of interface transitions and shared elements under that folder.
Specify the style of the transition animation for each activity in the Res/value/style file, and set the corresponding android:theme for each activity in the Androidmanifest.xml file.
startActivity()
use Activityoptionscompat to create a shared object when a transition animation is made before the activity call toggles the animation.
Here is a detailed explanation of these three steps.
Definition of animation of transitions
After you create a Transition resource folder under the Res/directory, you can define each animation under that folder.
In general, defining a transition animation for an activity can be written in the following form:
<explode xmlns:android= "Http://schemas.android.com/apk/res/android" >
<targets>
<target Android:excludeid= "@android: Id/statusbarbackground"/>
<target android:excludeid= "@android: Id/ Navigationbarbackground "/>
</targets>
</explode>
Where, is the name of the animation effect, the Android 5.0 (API level 21) supports these entry and exit conversions:
1, decomposition (explode): move from the scene center or move out of view.
2. Slide (slide): Move or move out of view from the edge of the scene.
3, Fade in (Fade): Add or remove views from the scene by adjusting the transparency.
And for each animation effect, there are additional attributes. For example, sliding slide can be used to android:slideEdge="top"
set the direction of sliding, fade (fade) can be used to android:fadingMode="fade_in"
set the specific fade (fade_in) or Fade (fade_out) and so on.
The tag defines a target ID that requires a transition (or does not require a transition). This ID allows the system to bring itself, or it can be the ID of the view in our own views, each ID needs to be defined separately in the label, android:targetId
indicating that the target ID needs a transition view, and android:excludeId
that we don't View with this ID is required for transition transitions. The above code means that all view, except the status bar and the navigation bar, performs explode animations.
What if we want to implement two or more animation effects in the same transition state? Also simple, replace the root tag with, and then define each animation effect, and finally remember to use in the root tag android:transitionOrdering
to indicate the sequence of these animations, sequential to express the order of execution, and together represents simultaneous execution.
Like the following code:
<transitionset xmlns:android= "Http://schemas.android.com/apk/res/android" >
<slide Android:slideedge = "Bottom" >
<targets>
<target android:targetid= "@id/cardview"/>
</targets>
</slide>
<fade>
<targets>
<target android:excludeid= "@android: Id/ Statusbarbackground "/>
<target android:excludeid=" @android: Id/navigationbarbackground "/>
< Target android:excludeid= "@id/cardview"/>
</targets>
</fade>
</transitionset >
The meaning of this code is simple, the XML defines two transition animations, and executes simultaneously. The first animation slides for view with ID CardView, and the second animation fades in and out of view except the status bar, navigation bar, and CardView.
Define the transition style for each activity
Each animation here refers to the state of the two interfaces in the transition to an interface jump. For example, for the two interfaces of activity A and activity B, the possible states are as follows:
1, interface a jump to interface B: At this time interface A is exit (exit) transition state, and the corresponding interface B is to enter (enter) transition state.
2, Interface B return to interface A: At this point interface A is a reenter transition, and the corresponding interface B is the return (returns) transition.
In general, all activity transition animations can be defined in the following form:
<style name= "Baseapptheme" parent= "android:Theme.Material" >
<!--open transition effect--> <item name=
" Android:windowcontenttransitions ">true</item>
<!--Specify interface entry/Exit animation effect-->
<item name=" Android:windowentertransition "> @transition/explode</item>
<item name=" Android: Windowexittransition "> @transition/explode</item>
<!--Specify the animation effect of a shared element entry/exit-->
<item name=" Android:windowsharedelemententertransition ">
@transition/change_image_transform</item>
< Item Name= "Android:windowsharedelementexittransition" >
@transition/change_image_transform</item>
</style>
Of course, you can not write full, for example, in my Demo, an interface of the animation file is as follows:
<style name= "Apptheme.detail" >
<item name= "Windowactionbar" >false</item>
<item name= "Android:windownotitle" >true</item>
<item name= "Android:windowtranslucentstatus" >true</ item>
<item name= "Android:windowallowentertransitionoverlap" >false</item>
<item name= " Android:windowentertransition "> @transition/detail_enter</item>
</style>
Iv. Call Activityoptionscompat
The transition animation occurs when the two-interface jump returns, so when using the intent jump interface, you need to call Activityoptionscompat to specify the animation's operation.
In general, the template code that invokes Activityoptionscompat is as follows:
Create a Activityoptions object that contains the transition animation information
activityoptions options = Activityoptions.makescenetransitionanimation (This, View, getString (R.string.image_transition_name));
Use the Intent jump interface and pass the shared object information
Intent Intent = new Intent (this, detailactivity.class);
StartActivity (Intent, Optionscompat.tobundle ());
Activityoptionscompat is in the support V4 package, but it is a compatible activityoptions (Activityoptions is introduced by API 16).
Then, we need to get and display the transitions picture in the second activity in the interface.
Transition implementations for multiple shared elements
Sometimes we need to animate multiple elements, and we can use pair<> to achieve:
Activityoptions options = Activityoptions.makescenetransitionanimation (This, pair.create (View1, "agreedName1"), Pair.create (View2, "agreedName2"));
Five, manually implement a transition animation
Now on the market, Android 5.0 under the mobile phone system also has a certain market share, so in order to take care of these users, we can only manually implement the animation effect of sharing elements.
The realization of the idea is also relatively simple, the approximate steps are as follows:
1, determine the first interface of the shared elements, the information passed a second interface
2, the second interface to receive information, at the beginning of the interface set to transparent, and only display the shared elements.
3, the second interface of the shared elements to animate.
So let's start with the steps above in a step-by-step way.
Get shared element location information
In the first interface, we need to get the location information for the shared element and pass it to the next interface. So, we can write this in the first interface element Click event:
public void ImageClick (view view) {
Intent Intent = new Intent (animeactivity.this, animedetailactivity.class);
Create a Rect object to store the shared element location information
Rect rect = new rect ();
Gets the element position information
view.getglobalvisiblerect (rect);
Attach the position information to the intent
intent.setsourcebounds (rect);
Customimage customimage = (customimage) view;
Intent.putextra (Animedetailactivity.extra_image, Customimage.getimageid ());
StartActivity (intent);
Shielding activity default Transitions effect
overridependingtransition (0, 0);
}
Where the getGlobalVisibleRect()
meaning of the method is to get the visible status bar height + the visible title bar height +rect the distance from the top left to the bottom of the title bar, and if the title bar is hidden, the visible title bar height is 0.
Next, you receive the location information in the second interface and display the image.
Simulate Transitions animation
In the second interface, we need to do the following:
1, get the shared element information.
2, calculate the share element scaling and displacement distance.
3, invoke animation, complete simulation transition effect.
I will follow the above three steps in the code below.
private void Initial () {//Get incoming information from previous interface mrect = Getintent (). Getsourcebounds ();
Mrescourceid = Getintent (). Getextras (). GetInt (Extra_image);
Gets the width and height of the picture in the previous interface moriginwidth = Mrect.right-mrect.left;
Moriginheight = Mrect.bottom-mrect.top; Sets the position of the ImageView to coincide with the position of the picture in the previous interface framelayout.layoutparams params = new Framelayout.layoutparams (Moriginwidth,
Moriginheight);
Params.setmargins (Mrect.left, Mrect.top-getstatusbarheight (), Mrect.right, Mrect.bottom);
Mimageview.setlayoutparams (params);
Set the ImageView picture and zoom type Mimageview.setimageresource (Mrescourceid);
Mimageview.setscaletype (ImageView.ScaleType.CENTER_CROP);
Gets the Bitmap object for the picture, based on the image resource ID passed in from the previous interface.
Bitmapdrawable bitmapdrawable = (bitmapdrawable) getresources (). getdrawable (Mrescourceid);
Bitmap Bitmap = Bitmapdrawable.getbitmap ();
Calculate picture scaling and displacement distance getbundleinfo (bitmap);
Create a Pallette object Mimagepalette = Palette.from (bitmap). Generate (); Use Palette to set the background color Mcontainer.setbackgroundcolor (mimagePalette.getvibrantcolor (This, Android. Contextcompat.getcolor.
R.color.black))); }
In line 12, by setting the form of Margin to determine the position of the picture, it should be noted that because the status bar is outside the parent control framlayout, we want to subtract the Rect.top value from the height of the status bar, which is the absolute position relative to the screen. Then the getBundleInfo()
code for the method is as follows:
private void Getbundleinfo (Bitmap Bitmap) {
//calculates picture scaling and is stored in bundle
if (bitmap.getwidth () >= Bitmap.getheight ()) {
mscalebundle.putfloat (scale_width, (float) mscreenwidth/moriginwidth);
Mscalebundle.putfloat (Scale_height, (float) bitmap.getheight ()/moriginheight);
else {
mscalebundle.putfloat (scale_width, (float) bitmap.getwidth ()/moriginwidth);
Mscalebundle.putfloat (Scale_height, (float) mscreenheight/moriginheight);
Calculate the displacement distance and store the data in the bundle
mtransitionbundle.putfloat (transition_x, MSCREENWIDTH/2-Mrect.left Rect.left)/2));
Mtransitionbundle.putfloat (transition_y, MSCREENHEIGHT/2-(Mrect.top + (Mrect.bottom-mrect.top)/2));
Animation processing
Finally we need to use animation to simulate the transition effect, the code is as follows:
private void Runenteranim () {
mimageview.animate ()
. Setinterpolator (default_interpolator)
. Setduration (DURATION)
. ScaleX (Mscalebundle.getfloat (scale_width))
. ScaleY (mscalebundle.getfloat HEIGHT))
. Translationx (Mtransitionbundle.getfloat (transition_x)).
Translationy ( Mtransitionbundle.getfloat (transition_y))
. Start ();
Very simple, since then, the entrance animation effect of the basic simulation completed.
And the exit animation is simpler, directly on the code:
private void Runexitanim () {
mimageview.animate ()
. Setinterpolator (default_interpolator)
. Setduration (DURATION)
. ScaleX (1)
. ScaleY (1)
. Translationx (0)
. Translationy (0)
. Withendaction (New Runnable () {
@Override public
void Run () {
finish ();
Overridependingtransition (0, 0);
}
})
. Start ();
}
Summarize
These are all the things that make the transition animation in Android, so is it easy? Hopefully the content of this article will be helpful to Android developers, and if you have any questions, you can leave a message to communicate.