Reprint please indicate the source: http://blog.csdn.net/lmj623565791/article/details/40411921, this article from: "Zhang Hongyang Blog" 1, overview
Previously wrote a blog post:Android custom Viewpager creates ever-changing picture transitions. a brother suggested that Viewpager brought a setpagetransformer for setting the toggle animation ~
This blog post will:
1, introduce how to use Setpagetransformer set to switch animation;
2, custom Pagetransformer to achieve the personality of the Switch animation;
3, the method in SDK11 the following version does not work, we will make certain changes to it, so that it is backward compatible.
Official example Address: http://developer.android.com/training/animation/screen-slide.html interested can go to see ~ ~
OK, here's how to write code ~ ~
2, the use of Setpagetransformer
First of all, we quickly realize a traditional viewpager effect ~
1. layout file
<relativelayout xmlns:android= "http://schemas.android.com/apk/res/android" xmlns:tools= "http// Schemas.android.com/tools " android:layout_width=" match_parent " android:layout_height=" Match_parent " > <android.support.v4.view.viewpager android:id= "@+id/id_viewpager" android:layout_width= " Fill_parent " android:layout_height=" Fill_parent "/></relativelayout>
2, Mainactivity
Package Com.zhy.demo_zhy_08_viewpageranim;import Java.util.arraylist;import Java.util.list;import Android.app.activity;import Android.os.bundle;import Android.support.v4.view.pageradapter;import Android.support.v4.view.viewpager;import Android.view.view;import Android.view.viewgroup;import Android.view.window;import Android.widget.imageview;import Android.widget.imageview.scaletype;public Class Mainactivity extends Activity{private viewpager mviewpager;private int[] mimgids = new int[] {r.drawable.guide_image1,r. Drawable.guide_image2, R.drawable.guide_image3};p rivate list<imageview> mimageviews = new ArrayList< Imageview> (); @Overrideprotected void OnCreate (Bundle savedinstancestate) {super.oncreate (savedinstancestate); Requestwindowfeature (Window.feature_no_title); Setcontentview (R.layout.activity_main); InitData (); MViewPager = ( Viewpager) Findviewbyid (R.id.id_viewpager); Mviewpager.setadapter (new Pageradapter () {@Overridepublic Object Instantiateitem (ViewGroup container, int position) {Container.addview (Mimageviews.get (position)); return mimageviews.get (position);} @Overridepublic void Destroyitem (ViewGroup container, int position,object Object) {Container.removeview ( Mimageviews.get (position));} @Overridepublic Boolean isviewfromobject (View view, Object object) {return view = = Object;} @Overridepublic int GetCount () {return mimgids.length;}});} private void InitData () {for (int imgid:mimgids) {ImageView ImageView = new ImageView (Getapplicationcontext ()); ImageView . Setscaletype (Scaletype.center_crop); Imageview.setimageresource (Imgid); Mimageviews.add (ImageView);}}
Well, such a traditional viewpager has been realized ~ ~ Everyone on the above code should not have any strange feeling ~ Operation effect also do not have stickers, we must know ~ ~
3, Pagetransformer
Viewpager has a method called:
The Setpagetransformer (boolean reversedrawingorder, Pagetransformer transformer) is used to set the animation effect when the Viewpager switch And two examples are also given by Google.
Just call Setpagetransformer in the code above to add the Toggle animation effect ~ ~ Below is a demonstration of Google's two Pagetransformer code, as well as the effect of the operation.
1, Depthpagetransformer
public class Depthpagetransformer implements Viewpager.pagetransformer {private static final float Min_scale = 0.75f; public void Transformpage (view view, float position) {int pagewidth = View.getwidth (); if (Position <-1) {//[-infinity,-1]//This page is the off-screen of the left. View.setalpha (0); } else if (position <= 0) {//[ -1,0]//Use the default slide transition when moving to the left page View.setalpha (1); View.settranslationx (0); View.setscalex (1); View.setscaley (1); } else if (position <= 1) {//(0,1]//Fade the page out. View.setalpha (1-position); CounterAct the default slide transition View.settranslationx (PageWidth *-position); Scale the PAGE down (between Min_scale and 1) Float scalefactor = Min_scale + (1-min_sc ALE) * (1-math.abs (position)); View.setscalex (Scalefactor); View.setscaley (Scalefactor); } else {//(1,+infinity]//This page is the off-screen of the right. View.setalpha (0); } }}
Calling code:
Mviewpager.setpagetransformer (True, New Depthpagetransformer ());
Effect:
2, Zoomoutpagetransformer
Package Com.zhy.view;import Android.annotation.suppresslint;import Android.support.v4.view.viewpager;import Android.util.log;import Android.view.view;public class Zoomoutpagetransformer implements viewpager.pagetransformer{ Private static final Float Min_scale = 0.85f;private static final float min_alpha = 0.5f; @SuppressLint ("Newapi") public voi D transformpage (view view, float position) {int pagewidth = view.getwidth (); int pageheight = View.getheight (); LOG.E ("TAG", View + "," + position + "); if (position <-1) {//[-infinity,-1]//This page is the--the Eft.view.setAlpha (0);} else if (position <= 1)//a page slides to page b; page a from 0.0-1; page b from 1 ~ 0.0{//[ -1,1]//Modify the default slide transition to shrink t He page as wellfloat scalefactor = Math.max (Min_scale, 1-math.abs (position)); float Vertmargin = PageHeight * (1-scalef Actor)/2;float Horzmargin = PageWidth * (1-scalefactor)/2;if (Position < 0) {View.settranslationx (horzmargin-ver TMARGIN/2);} Else{view.settranslaTionx (-horzmargin + VERTMARGIN/2);} Scale the PAGE down (between Min_scale and 1) view.setscalex (scalefactor); View.setscaley (scalefactor);//Fade the page R Elative to its Size.view.setAlpha (Min_alpha + (Scalefactor-min_scale)/(1-min_scale) * (1-min_alpha));} else{//(1,+infinity]//This page was the off-screen to the Right.view.setAlpha (0);}}
Calling code:
Mviewpager.setpagetransformer (True, New Zoomoutpagetransformer ());
Effect:
Are Google official online, our test map will be compatible with 3.0 below the paste out, or repeat the ~ ~
Adding a switch for Viewpager is not very happy, but it is not compatible with the version below 3.0, the comment on the method is written on:
Setting a Pagetransformer prior to Android 3.0 (API one) will have no effect in version prior to 3.0 setting this method is not effective, then we'll look at how to make it compatible with the following version 3.0.
3, version of Backward compatibility 1, incompatible reason
First of all see why incompatible, 3.0 or less?
Look at the above two sample code, the code in the view of the animation using the property animation, and property animation is 3.0 only introduced, then this is certainly not compatible with 3.0 below ~
Then we first introduce nineoldandroids, so that the animation can be run in the following 3.0:
Modify Depthpagetransformer
Package Com.zhy.view;import Com.nineoldandroids.view.viewhelper;import Android.annotation.suppresslint;import Android.support.v4.view.viewpager;import Android.view.view;public class Depthpagetransformer implements Viewpager.pagetransformer{private static final float Min_scale = 0.75f;public void Transformpage (view view, float Positio n) {int pagewidth = View.getwidth (); if (position <-1) {//[-infinity,-1]//This page is the same as the off-screen V Iew.setalpha (0); Viewhelper.setalpha (view, 0);} else if (position <= 0)//a page slides to page b; page a from 0.0-1; page b from 1 ~ 0.0{//[ -1,0]//use of the default slide transition when moving to The left page//View.setalpha (1); Viewhelper.setalpha (view, 1);//View.settranslationx (0); Viewhelper.settranslationx (view, 0);//View.setscalex (1); Viewhelper.setscalex (view, 1);//View.setscaley (1); Viewhelper.setscaley (view, 1);} else if (position <= 1) {//(0,1]//Fade the page out.//view.setalpha (1-position); Viewhelper.setalpha (view, 1-position);//CounterAct thE Default Slide transition//view.settranslationx (pagewidth *-position); Viewhelper.settranslationx (View, PageWidth *-position);//Scale the PAGE down (between Min_scale and 1) float Scalefactor = Min_scale + (1-min_scale) * (1-position);//View.setscalex (scalefactor); Viewhelper.setscalex (view, scalefactor);//View.setscaley (1); Viewhelper.setscaley (view, scalefactor);} else{//(1,+infinity]//This page was the off-screen to the right.//view.setalpha (0); Viewhelper.setalpha (view, 1);}}
It's easy to change all the property animations into Viewhelper to set it up. Now we go to 3.0 below the machine up and running, found still no effect ~ ~ ~
Why is it?
Let's take a look at Setpagetransformer's source code:
public void Setpagetransformer (Boolean reversedrawingorder, Pagetransformer transformer) { if (Build.VERSION.SDK_ INT >= one) { final Boolean hastransformer = transformer! = NULL; Final Boolean needspopulate = Hastransformer! = (Mpagetransformer! = null); Mpagetransformer = transformer; Setchildrendrawingorderenabledcompat (Hastransformer); if (hastransformer) { Mdrawingorder = Reversedrawingorder? Draw_order_reverse:draw_order_forward; } else { mdrawingorder = Draw_order_default; } if (needspopulate) populate (); } }
Finally discovered the reason, originally in this method internal judgment if is 11 above the version only then lets the animation take effect ~ ~
Then, no way, if you want to be compatible, you must modify the source of the Viewpager ~ ~
2. Perfect backwards compatibility
We will copy the source code of Viewpager to our project, modify the name to Viewpagercompat, then comment out the SDK version to judge the sentence
public class Viewpagercompat extends ViewGroup {
public void Setpagetransformer (Boolean reversedrawingorder, Viewpager.pagetransformer transformer) {// if ( Build.VERSION.SDK_INT >= one) { final Boolean hastransformer = transformer! = NULL; Final Boolean needspopulate = Hastransformer! = (Mpagetransformer! = null); Mpagetransformer = transformer; Setchildrendrawingorderenabledcompat (Hastransformer); if (hastransformer) { Mdrawingorder = Reversedrawingorder? Draw_order_reverse:draw_order_forward; } else { mdrawingorder = Draw_order_default; } if (needspopulate) populate (); } }
...
}
Note that all Pagetransformer use Viewpager.pagetransformer
Then we change the Viewpager in the project to Viewpagercompat; Remember to modify the layout file and Viewpager in mainactivity as Viewpagercompat
We tested the effect on the 2.3.3 simulator:
Can see, our switch animation perfect running on 2.3.3 machine ~~so Happy ~ ~ No Viewpager the source of children's shoes do not matter, I will be in the end of the source code download to add Viewpager source code, so you can go to test ~ ~
Of course, is only compatible, of course, can not satisfy our curiosity, we do the compatibility, but also can only use Google to give the sample animation ~ ~ Our strong innovation ~ ~ below to lead you to analyze the Setpagetransformer method, and then design a personality animation switch effect
4, custom Pagetransformer to achieve personalized switch animation
Public interface Pagetransformer { /** * Apply a property transformation to the given page. * * @param page Apply The transformation to this page * @param position position of page relative to the current F Ront-and-center * position of the pager. 0 is front and center. 1 are one full * page position to the right And-1 is a page position to the left. * /public void Transformpage (View page, float position); }
You can see that the interface has only one method, the first one is our view, the second one is position~~
When we swipe: will print out of course viewpager in the survival of each view and their position changes ~ ~ Note is each, so it is recommended not only log position, otherwise you will feel inexplicable output ~ ~
The value of the probability of position is, in fact, from the official example of the comments can be seen:
[-infinity,-1] has not been seen.
(1,+infinity] have not seen
[ -1,1]
Focus on [ -1,1] This interval, the other two view has not been seen ~ ~
Assuming that Viewpager now slides out B on page A, then:
The position change on page A is (0,-1]
The position change on page b is [1, 0]
Know the change of position when we slide ~ ~ then began to design our personality switch effect;
The official gives the example, has the change transparency, the offset, the scale, we prepare to have a different, our change angle, namely rotation;
The approximate effect is this:
Here we analyze the code:
We set the rotation center of the view to:
Viewhelper.setpivotx (view, View.getmeasuredwidth () * 0.5f);
Viewhelper.setpivoty (view, View.getmeasuredheight ());
Still Viewpager on page a now slide out of page b
Then page A should be in the sliding process 0 degrees to 20 degrees of deviation, b page should be in the sliding process +20 degrees to 0 degrees offset
Combine
The position change on page A is (0,-1]
The position change on page b is [1, 0]
Then the angle of rotation is: Mrot = (position); Page a mrot:0, ~-20; Page b mrot:20 ~ 0;
Instantly feel good simple:
Full code:
Package Com.zhy.view;import Com.nineoldandroids.view.viewhelper;import Android.annotation.suppresslint;import Android.support.v4.view.viewpager;import Android.util.log;import Android.view.view;public Class Rotatedownpagetransformer implements viewpager.pagetransformer{private static final float Rot_max = 20.0f;private float mrot;public void Transformpage (view view, float position) {LOG.E ("TAG", View + "," + position + "); if (position <-1) {//[-infinity,-1]//This page was the off-screen to the left. Viewhelper.setrotation (view, 0);} else if (position <= 1)//page A slides to page B; page A from 0.0 to 1; page b from 1 ~ 0.0{//[ -1,1]//Modify the default slide transition to Shrin K the page as Wellif (position < 0) {Mrot = (Rot_max * position); Viewhelper.setpivotx (view, View.getmeasuredwidth () * 0.5f); Viewhelper.setpivoty (view, View.getmeasuredheight ()); Viewhelper.setrotation (view, Mrot);} Else{mrot = (Rot_max * position); Viewhelper.setpivotx (view, View.getmeasuredwidth () * 0.5f); Viewhelper.setpivoty (View, View.getmeasuredheight ()); Viewhelper.setrotation (view, Mrot);} Scale the page is down (between Min_scale and 1)//Fade the page relative to its size.} else{//(1,+infinity]//This page is the off-screen of the right. Viewhelper.setrotation (view, 0);}}
You are right, if else inside the code is the same, in order to understand deliberately not merged together ~ ~ ~
To this, we use from the Setpagetransformer, to modify the Viewpager to achieve backward compatibility, until the definition of their own personality switch effect has been introduced ~ ~
Everyone can play their own creativity, make a variety of magical animation effect, OK, here!
If you like custom Viewpager, move: Android custom Viewpager to create ever-changing picture transitions
SOURCE Click to download
---------------------------------------------------------------------------------------------------------
Bo Master part of the video has been online, if you do not like boring text, please poke (first record, look forward to your support):
1, High imitation 5.2.1 main interface and message alert
2, high imitation QQ5.0 slide
Android realizes personality Viewpager Switch Animation combat Pagetransformer (compatible with Android3.0 below)