Reprint Please specify source:http://blog.csdn.net/allen315410/article/details/44224517
In my previous blog, I wrote a way to add toggle animations to Viewpager using property animations. and can be compatible with Android3.0 the following version of the device, then about the way to add animation for Viewpager there will be another implementation, is to customize a self-animated viewpager, about the previous blog, have not had time to view the friends can Click here to view. Next, we'll create a new project that says how to customize a viewpager that comes with a toggle animation effect.
Analysis
First of all, let's analyze what we need to get when we implement custom Viewpager to switch animation effects. First, we know that Viewpager to switch back and forth, is actually different view on the screen to switch, so we need to customize the Viewpager to get the current switch 2 view. Second, since we are adding animations to Viewpager, we need to customize the animation. OK, the above two points are what is needed in this custom viewpager, we step by step to create and get to it.
Next, I create a new class Viewpagerwithtransformer inherits from Viewpager, to implement the custom Viewpager. First, we rewrite a method in Viewpager, the code is as follows, we print the method in the parameter, in the layout file with this custom Viewpager, in the activity for this Viewpager add data adapter, Add 3 ImageView to Viewpager, implement the Viewpager on the switch, the code can be seen in the previous blog mainactivity.
@Overrideprotected void onpagescrolled (int position, float offset, int offsetpixels) {super.onpagescrolled (position, Offset, offsetpixels); LOG.I ("TAG", "position =" + position + ", offset =" + offset + ", Offsetpixels =" + Offsetpixels);}
The parameters in the above method have already been printed, the log output logs are below, first look at the log from page No. 0 to page 1th:
Then, look at the log from page 1th to page No. 0:
Analyze the log logs above:
When page No. 0 and 1th: Position from 0-->1;offset from 0-->1;offsetpixels to 0--> screen maximum width
When page 1th and No. 0: Position from 1-->0;offset from 1-->0;offsetpixels to 0--> screen maximum width
Clearly perceptible, only position represents the position currently switching view, offset represents the offset weight of the view, and Offsetpixels represents the view's actual offset (px).
Gets the View object in the toggle
"Error" above we analyze we then customize a drive to switch the Viewpager, need to get the 2 view object being switched, then how can we get the 2 view object in the code? You know, in the last blog we used viewpager source code, Viewpager's parent class is viewgroup, we know in ViewGroup want to get the view object, there is a getchildat (int index) Method can get the view object, the method used in the ViewGroup is not a problem, and then use in the Viewpager error, because viewpager in the cache mechanism, a viewpager by default can only cache 2-3 view objects, When more view objects are loaded into Viewpager, Viewpager discards the previous view object, which causes us to not pass getchildat (position), Getchildat (position-1), Getchildat (position+1) method to get the previous, current, and next view object, it is obvious that the position represents more than two or three view objects, but is infinite.
"Error" through Getchildat (position) Obviously not get the object we want, since can not use position, ViewGroup also has a getcurrentitem () Is it possible to get the current view's Corner and Getchildcount () methods to get the view number? Let's first print the log logs in the Onpagescrolled () method.
We can see that the value of Getcurrentitem is constantly changing, and when we open page 1th, getcurrentitem=0, this is what we can bring into getchildat based on the value of this getcurrentitem ( getCurrentItem-1), Getchildat (Getcurrentitem), Getchildat (getcurrentitem+1), you can actually get to the previous view, the current view, the next view. Then unfortunately, when our fingers are released from the screen, the Getcurrentitem becomes 1, and the view previously obtained by Getchildat (Getcurrentitem) is wrong. So it's not right to get a view based on Getcurrentitem ().
"correct" through the above 2 methods can not accurately get to the current view object, we will look at position this parameter. In combination with the log input above, when we slide the No. 0 page to page 1th in Viewpager, the position is unchanged, at this time pisition=0; when we slide from page 1th to page No. 0, position hasn't changed yet. At this time position=0, whether we can still determine the object of the view according to position, we assume that position represents the view on page No. 0, then position+1 is the view representing page 1th. And so on you can get all the view. Below, we can be in the code to implement our ideas, but also particularly simple, is to create a map collection to do a caching mechanism for view, we use position as the key, using the View object as a value, and provides a way to add a view cache and a way to remove the view cache. When we provide adapter pageradapter for Viewpager, you can set the view object into the cache collection of the view in the Instantiateitem (ViewGroup container, int position) method. Removes the view from the cache collection in the Destroyitem (ViewGroup container, int position, Object object) method. The specific part of the code is as follows:
Save Viewpager on View object Private Map<integer, view> Mviewcache = new Hashmap<integer, view> ();/** * Set the cache for view *< c0/>* @param position * @param viewcache*/public void Setviewcache (Integer position, View Viewcache) {mviewcache.put (posi tion, viewcache);} /** * Removes the view of the specified position from the view's cache collection * * @param position */public void Removeviewcache (Integer position) { Mviewcache.remove (position);}
Switch the implementation of the animation above resolves a headache problem, if you get the view object being switched, the problem has been solved above, then there is only animation. In this case we mimic the Depthpagetransformer animation effect in the previous blog, we customize two animations, a scale animation and a translate animation, To make two animation alternately executed together can imitate depthpagetransformer this kind of translation zoom animation effect comes out, the code is very simple, do not post separately, below have complete code.
Complete code customization Viewpager source, Viewpagerwithtransformer.java
public class Viewpagerwithtransformer extends Viewpager {//left viewprivate view mleftview;//to the right viewprivate view MRIGHTVI ew;//translation animation gradient value private float mtranslate;//scale animation gradient value private float mscale;//minimum scaling private static final float Min_scale = 0.6 f;//save Viewpager on view object Private Map<integer, view> Mviewcache = new Hashmap<integer, view> ();/** * Set the cache for view * * @param position * @param viewcache */public void Setviewcache (Integer position, View Viewcache) {mviewcache.put (posit Ion, Viewcache);} /** * Removes the view of the specified position from the view's cache collection * * @param position */public void Removeviewcache (Integer position) {Mviewcache.remove (position);} Public Viewpagerwithtransformer (context context, AttributeSet Attrs) {Super (context, attrs);//TODO auto-generated constructor stub} @Overrideprotected void onpagescrolled (int position, float offset, int offsetpixels) { super.onpagescrolled (position, offset, offsetpixels); Mleftview = Mviewcache.get (position); Mrightview = Mviewcache.get (position + 1); Animstack (mLeFtview, Mrightview, offset, offsetpixels);} private void Animstack (view left, view right, float offset, int. offsetpixels) {//TODO auto-generated method Stubif (right ! = NULL) {//From page No. 0--"to page 1th, offset:0~1, scale Mscale:0.6~1mscale = (1-min_scale) * offset + min_scale;//panning distance mtranslate =-ge Twidth ()-getpagemargin () + offsetpixels;//use Nineoldandroids to write property animation Viewhelper.setscalex (right, Mscale); Viewhelper.setscaley (right, Mscale); Viewhelper.settranslationx (right, mtranslate);} if (left! = null) {//the page on the top is always Left.bringtofront ();}}}
Stated in the layout file, Activity_main.xml
<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 " > <com.example.viewpagerwithtransformeranim.viewpagerwithtransformer android:id= "@+id/viewpager" android:layout_width= "match_parent" android:layout_height= "match_parent" > </ Com.example.viewpagerwithtransformeranim.viewpagerwithtransformer></relativelayout>
Use this control in activity, Mainactivity.java
public class Mainactivity extends Activity {private int[] imgres = new int[] {r.drawable.guide_image1, r.drawable.guide_i Mage2, R.drawable.guide_image3};p rivate list<imageview> imglist = new arraylist<imageview> ();p rivate Viewpagerwithtransformer Mviewpager; @Overrideprotected void OnCreate (Bundle savedinstancestate) {super.oncreate ( Savedinstancestate); requestwindowfeature (Window.feature_no_title); Setcontentview (R.layout.activity_main); Mviewpager = (Viewpagerwithtransformer) Findviewbyid (R.id.viewpager); Mviewpager.setadapter (new PagerAdapter () {@ Overridepublic boolean isviewfromobject (View arg0, Object arg1) {return arg0 = = arg1;} @Overridepublic int GetCount () {return imgres.length;} @Overridepublic Object Instantiateitem (viewgroup container, int position) {ImageView Mimageview = new ImageView ( Mainactivity.this); Mimageview.setbackgroundresource (Imgres[position]); Mimageview.setscaletype (ScaleType.CENTER _crop); Imglist.add (Mimageview);//Set view cache for Viewpager Mviewpager.setviewcachE (position, mimageview); Container.addview (Mimageview); return mimageview;} @Overridepublic void Destroyitem (ViewGroup container, int position, object object) {// Remove Viewpager View cache Mviewpager.removeviewcache (position); Container.removeview (Imglist.get (position));}});}}
Good, all the source on the above, notice, in the adapter Pageradapter to Viewpager set to rewrite Instantiateitem method, be sure to remember to call Mviewpager.setviewcache (position, Mimageview) method, set the view cache to Viewpager, and then call the Mviewpager.removeviewcache (position) method in the override Destroyitem method to remove the view cache.Thanks to CSDN Blog expertHon Yangselfless dedication to tutorials, tutorials video address:http://www.imooc.com/learn/226
please download the source code here
Android adds toggle animations for Viewpager-custom Viewpager