開篇
作爲我的第一篇博客,可能寫的時候還有些粗糙,知識點的敘述也不夠明確,不過這纔是開始,而且每一篇博客都會用心去編寫,所寫的內容都是自己在學習安卓中的一些發現和見解,基於我的技術水平有限,如有不足的可以留言,有錯誤的地方也請及時批評指出。
沒有前戲,直接上重點
因爲是自己的第一篇,也是我第一次寫博客,對於各種排版的問題,大家可以忽略,重點是代碼和一些重要的說明我都會用粗體標出的。
關於ViewPager 的基本使用和適配器的創建,這些內容在本文中都沒有,在網上有很多資料的,本文重點是在過渡動畫
或者說這篇文章主要是研究ViewPager的一個方法setPageTransformer(),這是在API11,也就是android3.0之後安卓官方給我們提供的一個能夠改變ViwePager過渡動畫的一個方法,或者說接口。
先看一下源碼,本人英語水平有限,大家自行理解閱讀吧,怕誤導各位了。
/** * Set a {@link PageTransformer} that will be called for each attached page whenever * the scroll position is changed. This allows the application to apply custom property * transformations to each page, overriding the default sliding look and feel. * * <p><em>Note:</em> Prior to Android 3.0 the property animation APIs did not exist. * As a result, setting a PageTransformer prior to Android 3.0 (API 11) will have no effect.</p> * * @param reverseDrawingOrder true if the supplied PageTransformer requires page views * to be drawn from last to first instead of first to last. * @param transformer PageTransformer that will modify each page's animation properties */ public void setPageTransformer(boolean reverseDrawingOrder, PageTransformer transformer) { if (Build.VERSION.SDK_INT >= 11) { 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(); }
android官方文檔上也對於這個方法的使用,感興趣的可以參考一下。(我記得有,不過剛纔找了沒找到,丟人啊!)
精華部分
這是我自己經過多次試驗之後得到的代碼與結論,可以直接看代碼,代碼中的註釋也許會讓你對這個方法產生一種感覺,原來改變動畫這麼簡單
vp.setPageTransformer(true, new PageTransformer() { @Override public void transformPage(View view, float position) { float mdistance=0.5f; if(position<-1){ //設置成不可見就可以 view.setAlpha(0); }else if(position<=0){ //小於零的position所對應的是在屏幕左邊的view //劃入屏幕時position是從-1到0 //劃出屏幕時position是從0到-1 //執行縮放時,不設置中心點會自動選擇view中心 view.setAlpha(1+position); view.setScaleY((position+1)/2+mdistance); }else if(position<=1){ //大於零的position所對應的是在屏幕右邊的view //劃入屏幕的時候position是從1到0 //劃出屏幕的時候position是從0到1 //執行縮放時,不設置中心點會自動選擇view的中心 view.setAlpha(1-position); view.setScaleY((1-position)/2+mdistance); }else { //設置成不可見就可以 view.setAlpha(0); } } });
現在給大家稍微解釋一下,ViewPager在調用setPageTransformer()方法後會要求重寫一個方法就是transformPage(),其實就是重寫ViewPager的一個內部接口裏的方法,重要的是方法的參數,第一個是view,可以不管他,重點是第二個position,網上很多資料,官方也給了一下說明,大概的意思就是當處於屏幕正中的時候position是0,當左邊的view恰好劃出屏幕時是-1,右邊的view恰好劃入的時候是1。當我讀這種解釋的時候,完全不理解是什麼意思,還有說左右兩邊各佔屏幕一半的時候,左邊的是-0.5,右邊的是+0.5,不懂之後我就進行了一系列的試驗,最終得出了代碼中註釋部分的結論。
首先position小於0就是指屏幕左邊的view的位置,position大於0就是指屏幕右邊的view的位置,小於-1和大於1均可以不用考慮,因爲看不見的。
對於position小於0來說,也就是相對於屏幕左邊的view來說有兩種情況,一種就是劃入屏幕,此時position的變化是從-1到0的,另一種就是劃出屏幕,此時position的變化是從0到-1的。這都是指屏幕左邊的view。
對於position大於0來說,也就是相對於屏幕右邊的view來說也有兩種情況,一種劃入時,position變化是從1到0,另一種就是劃出時,position變化是從0到1。這裏指的是屏幕右邊的view。
當我們瞭解了position的基本變化了之後就是一嘗試實現自己想要的動畫效果了,對於小於-1和大於1的情況可以直接設置透明度爲0就可以了,官方也是這麼寫的。當處於-1到0,和0到1之間時,這個時候可以調用view的各種set方法來實現你想要的動畫效果,透明度啊,縮放啊,平移啊,旋轉啊,都可以,重點的是對於position(位置)的理解。
對於相對於在屏幕左邊的view來說,我們只需要設置劃出或者劃入時的一種動畫方案即可,因爲兩種情況下position的變化是相對的,但是如果你想得到更復雜的動畫效果,比如劃入的時候採用縮放的方式進入,劃出的時候採用旋轉的方式劃出,這也是可以的,這需要你對position的變化進行判斷,來決定採用什麼樣的過場動畫,通常情況下,我們只需要寫一種就可以了。
對於動畫的實現方案,這就可以根據個人喜好取設置了,剩下的都是邏輯問題,大家可以自行去嘗試實現一下,其實也挺好玩的,附上代碼中所實現的效果,真的挺簡單的。(這個怎麼插入動畫效果啊?)好吧,等我之後的文章在上圖吧,現在有點研究不明白這個博客怎麼上效果圖了,那這篇文章到這就結束了。
總結一下吧!
先說一下在我最近使用中遇到的問題,昨天在使用viewpager+fragment的時候遇到了,發現在更改了過渡動畫了之後在左右滑動的時候,如果不滑動到屏幕的邊界的話,fragment所對應的視圖不會充滿屏幕的,會保持在手指離開屏幕時view的狀態,但在功能上沒有問題,不知道是哪裏出了毛病。
作爲我的第一文章,寫得有點亂,也沒有什麼內容,至少對於一個方法中一個參數的變化過程的分析,不過這確實是我經過獨立的實踐之後發現的結論(油然而生的成就感),希望能夠對看這文章的能有所幫助,同時也歡迎批評指正,多多交流。