閱讀294 返回首頁    go 阿裏雲 go 技術社區[雲棲]


Android 深入ViewPager補間動畫,實現類京東商城首頁廣告Banner切換效果

如有轉載,請聲明出處: 時之沙: https://blog.csdn.net/t12x3456


某天看到京東商城首頁的滑動廣告的Banner,在流動切換的時候有立體的動畫效果,感覺很有意思,然後研究了下如何實現. 

廢話不多說,接下來我會講述如何實現這種效果,以及如何根據需求自定義出新的動畫效果進行擴展實現.


首先還是看一下京東商城上的效果:

                                                


像一般做這種效果怎麼辦呢?我的建議還是先在github或者google code上搜索開源庫. 一來開源庫一般做得比較成熟,API封裝得較好,耦合性比較低. 二來項目比較利於維護.

(並不是說全自己實現的就不好,畢竟每個人實現的思路並不一樣,相對於開源庫來說,閱讀別人的曆史代碼就相對比較麻煩,有bug或者有新需求的話,會很影響開發的效率)

下麵還是直接上項目, 如上所示的效果已經有開源庫的實現,而且還有很多其他動畫補間效果:


JazzViewPager簡介:

github地址: https://github.com/jfeinstein10/JazzyViewPager

該項目是基於ViewPager的一個重寫,讓我們看一下自帶的Demo項目結構:



 這裏我們可以看到,ViewPager的動畫效果由nineoldandroids這個開源項目實現:

github地址:

  https://github.com/JakeWharton/NineOldAndroids

該動畫庫將Android3.0以上版本API實現的動畫做了重寫,可以兼容到3.0以下的版本


JazzyViewPager的集成:

接下來我們看一下如何將該開源庫集成到自己的項目中:

1.布局文件中遵照自定義控件的寫法即可:

  1. <com.jfeinstein.jazzyviewpager.JazzyViewPager  
  2.     xmlns:android="https://schemas.android.com/apk/res/android"  
  3.     xmlns:app="https://schemas.android.com/apk/res-auto"  
  4.     android:id="@+id/jazzy_pager"  
  5.     android:layout_width="match_parent"  
  6.     android:layout_height="match_parent" />  

2.設置ViewPager的動畫效果:

這裏首先介紹一下目前已經封裝好的效果:

JazzyViewPager中的的枚舉類:

  1. public enum TransitionEffect {  
  2.         Standard,  
  3.         Tablet,  
  4.         CubeIn,  
  5.         CubeOut,  
  6.         FlipVertical,  
  7.         FlipHorizontal,  
  8.         Stack,  
  9.         ZoomIn,  
  10.         ZoomOut,  
  11.         RotateUp,  
  12.         RotateDown,  
  13.         Accordion  
  14.     }  

怎麼設置呢?非常簡單:

  1. private JazzyViewPager mJazzy;  
  2. /* ... */  
  3. mJazzy.setTransitionEffect(TransitionEffect.*);  

在京東商城使用的效果即為TransitionEffect.CubeOut


這裏我們還可以看一下其他的效果

TransitionEffect.Tablet

                                  


TransitionEffect.Stack

                                  

其他效果大家可以自己嚐試下.


3.集成該開源庫需要注意一些事項:

當ViewPager中的子View超過三個的時候,我們需要對PagerAdapter修改,重寫InstantiateItem()方法,,會導致補間動畫不能正常顯示.

EX:

  1. private JazzyViewPager mJazzy;  
  2. /* ... */  
  3. @Override  
  4. public Object instantiateItem(ViewGroup container, final int position) {  
  5.     Object obj = super.instantiateItem(container, position);  
  6.     mJazzy.setObjectForPosition(obj, position);  
  7.     return obj;  
  8. }  

JazzyViewPager的修改:

如果大家還是嫌目前已經封裝的效果還是不滿意怎麼辦?項目有其他動畫實現的需求怎麼辦?這裏順便講下如何擴展該開源庫:(紅色部分為需要添加修改的代碼)

1.在枚舉類中添加所需的動畫效果,這裏以Test代替.

  1. public enum TransitionEffect {  
  2.         Standard,  
  3.         Tablet,  
  4.         CubeIn,  
  5.         CubeOut,  
  6.         FlipVertical,  
  7.         FlipHorizontal,  
  8.         Stack,  
  9.         ZoomIn,  
  10.         ZoomOut,  
  11.         RotateUp,  
  12.         RotateDown,  
  13.         Accordion,  
  14.         <span style="color:#FF0000;">Test</span>  
  15.  }  

2.增加動畫效果的具體實現:
  1. protected void animateTest(View left, View right, float positionOffset) {     
  2.  if (mState != State.IDLE) {  
  3.   if (left != null) {  
  4.    //此處增加具體動畫  
  5.  }  
  6.   if (right != null) {  
  7.    //此處增加具體動畫實現   
  8.  }  
  9.  }  
  10. }  


3.在onPageScrolled的方法中,增加對應效果的處理:

  1. @Override  
  2. public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {  
  3.   if (mState == State.IDLE && positionOffset > 0) {  
  4.   oldPage = getCurrentItem();  
  5.   mState = position == oldPage ? State.GOING_RIGHT : State.GOING_LEFT;  
  6. }  
  7. boolean goingRight = position == oldPage;     
  8. if (mState == State.GOING_RIGHT && !goingRight)  
  9.   mState = State.GOING_LEFT;  
  10.   else if (mState == State.GOING_LEFT && goingRight)  
  11.   mState = State.GOING_RIGHT;  
  12.   
  13.   float effectOffset = isSmall(positionOffset) ? 0 : positionOffset;  
  14.   
  15.   // mLeft = getChildAt(position);  
  16.   // mRight = getChildAt(position+1);  
  17.   mLeft = findViewFromObject(position);  
  18.   mRight = findViewFromObject(position+1);  
  19.   
  20.   if (mFadeEnabled)  
  21.   animateFade(mLeft, mRight, effectOffset);  
  22.   if (mOutlineEnabled)  
  23.   animateOutline(mLeft, mRight);  
  24.   
  25.   switch (mEffect) {  
  26.   case Standard:  
  27.   break;  
  28.   case Tablet:  
  29.   animateTablet(mLeft, mRight, effectOffset);  
  30.   break;  
  31.   case CubeIn:  
  32.   animateCube(mLeft, mRight, effectOffset, true);  
  33.   break;  
  34.   case CubeOut:  
  35.   animateCube(mLeft, mRight, effectOffset, false);  
  36.   break;  
  37.   case FlipVertical:  
  38.   animateFlipVertical(mLeft, mRight, positionOffset, positionOffsetPixels);  
  39.   break;  
  40.   case FlipHorizontal:  
  41.   animateFlipHorizontal(mLeft, mRight, effectOffset, positionOffsetPixels);  
  42.   case Stack:  
  43.   animateStack(mLeft, mRight, effectOffset, positionOffsetPixels);  
  44.   break;  
  45.   case ZoomIn:  
  46.   animateZoom(mLeft, mRight, effectOffset, true);  
  47.   break;  
  48.   case ZoomOut:  
  49.   animateZoom(mLeft, mRight, effectOffset, false);  
  50.   break;  
  51.   case RotateUp:  
  52.   animateRotate(mLeft, mRight, effectOffset, true);  
  53.   break;  
  54.   case RotateDown:  
  55.   animateRotate(mLeft, mRight, effectOffset, false);  
  56.   break;  
  57.   case Accordion:  
  58.   animateAccordion(mLeft, mRight, effectOffset);  
  59.   break;  
  60.   <span style="color:#FF0000;">case</span> <span style="color:#FF0000;">Test:   </span><span class="nf">  
  61. <span style="color:#FF0000;">  animateTest</span></span><span style="color:#FF0000;"><span class="o"></span>(mLeft, mRight, effectOffset);  
  62.   break;  
  63. </span> }  
  64.   
  65. super.onPageScrolled(position, positionOffset, positionOffsetPixels);  
  66.   
  67. if (effectOffset == 0) {  
  68. disableHardwareLayer();  
  69. mState = State.IDLE;  
  70. }  
  71.   
  72. }  

經過這三步,我們就可以添加具有新的補間動畫的ViewPager. 這裏大家可以盡情發揮自己的創意,不斷地擴展該開源庫,實現自己想要的效果.

Demo下載地址:https://download.csdn.net/detail/t12x3456/6468601

最後更新:2017-04-03 12:53:47

  上一篇:go android 按鍵聲音
  下一篇:go Galera/mysql 集群 備忘