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.布局文件中遵照自定義控件的寫法即可:
- <com.jfeinstein.jazzyviewpager.JazzyViewPager
- xmlns:android="https://schemas.android.com/apk/res/android"
- xmlns:app="https://schemas.android.com/apk/res-auto"
- android:id="@+id/jazzy_pager"
- android:layout_width="match_parent"
- android:layout_height="match_parent" />
2.設置ViewPager的動畫效果:
這裏首先介紹一下目前已經封裝好的效果:
JazzyViewPager中的的枚舉類:
- public enum TransitionEffect {
- Standard,
- Tablet,
- CubeIn,
- CubeOut,
- FlipVertical,
- FlipHorizontal,
- Stack,
- ZoomIn,
- ZoomOut,
- RotateUp,
- RotateDown,
- Accordion
- }
怎麼設置呢?非常簡單:
- private JazzyViewPager mJazzy;
- /* ... */
- mJazzy.setTransitionEffect(TransitionEffect.*);
在京東商城使用的效果即為TransitionEffect.CubeOut
這裏我們還可以看一下其他的效果
TransitionEffect.Tablet
TransitionEffect.Stack
其他效果大家可以自己嚐試下.
3.集成該開源庫需要注意一些事項:
當ViewPager中的子View超過三個的時候,我們需要對PagerAdapter修改,重寫InstantiateItem()方法,,會導致補間動畫不能正常顯示.
EX:
- private JazzyViewPager mJazzy;
- /* ... */
- @Override
- public Object instantiateItem(ViewGroup container, final int position) {
- Object obj = super.instantiateItem(container, position);
- mJazzy.setObjectForPosition(obj, position);
- return obj;
- }
JazzyViewPager的修改:
1.在枚舉類中添加所需的動畫效果,這裏以Test代替.
- public enum TransitionEffect {
- Standard,
- Tablet,
- CubeIn,
- CubeOut,
- FlipVertical,
- FlipHorizontal,
- Stack,
- ZoomIn,
- ZoomOut,
- RotateUp,
- RotateDown,
- Accordion,
- <span style="color:#FF0000;">Test</span>
- }
2.增加動畫效果的具體實現:
- protected void animateTest(View left, View right, float positionOffset) {
- if (mState != State.IDLE) {
- if (left != null) {
- //此處增加具體動畫
- }
- if (right != null) {
- //此處增加具體動畫實現
- }
- }
- }
3.在onPageScrolled的方法中,增加對應效果的處理:
- @Override
- public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
- if (mState == State.IDLE && positionOffset > 0) {
- oldPage = getCurrentItem();
- mState = position == oldPage ? State.GOING_RIGHT : State.GOING_LEFT;
- }
- boolean goingRight = position == oldPage;
- if (mState == State.GOING_RIGHT && !goingRight)
- mState = State.GOING_LEFT;
- else if (mState == State.GOING_LEFT && goingRight)
- mState = State.GOING_RIGHT;
- float effectOffset = isSmall(positionOffset) ? 0 : positionOffset;
- // mLeft = getChildAt(position);
- // mRight = getChildAt(position+1);
- mLeft = findViewFromObject(position);
- mRight = findViewFromObject(position+1);
- if (mFadeEnabled)
- animateFade(mLeft, mRight, effectOffset);
- if (mOutlineEnabled)
- animateOutline(mLeft, mRight);
- switch (mEffect) {
- case Standard:
- break;
- case Tablet:
- animateTablet(mLeft, mRight, effectOffset);
- break;
- case CubeIn:
- animateCube(mLeft, mRight, effectOffset, true);
- break;
- case CubeOut:
- animateCube(mLeft, mRight, effectOffset, false);
- break;
- case FlipVertical:
- animateFlipVertical(mLeft, mRight, positionOffset, positionOffsetPixels);
- break;
- case FlipHorizontal:
- animateFlipHorizontal(mLeft, mRight, effectOffset, positionOffsetPixels);
- case Stack:
- animateStack(mLeft, mRight, effectOffset, positionOffsetPixels);
- break;
- case ZoomIn:
- animateZoom(mLeft, mRight, effectOffset, true);
- break;
- case ZoomOut:
- animateZoom(mLeft, mRight, effectOffset, false);
- break;
- case RotateUp:
- animateRotate(mLeft, mRight, effectOffset, true);
- break;
- case RotateDown:
- animateRotate(mLeft, mRight, effectOffset, false);
- break;
- case Accordion:
- animateAccordion(mLeft, mRight, effectOffset);
- break;
- <span style="color:#FF0000;">case</span> <span style="color:#FF0000;">Test: </span><span class="nf">
- <span style="color:#FF0000;"> animateTest</span></span><span style="color:#FF0000;"><span class="o"></span>(mLeft, mRight, effectOffset);
- break;
- </span> }
- super.onPageScrolled(position, positionOffset, positionOffsetPixels);
- if (effectOffset == 0) {
- disableHardwareLayer();
- mState = State.IDLE;
- }
- }
經過這三步,我們就可以添加具有新的補間動畫的ViewPager. 這裏大家可以盡情發揮自己的創意,不斷地擴展該開源庫,實現自己想要的效果.
Demo下載地址:https://download.csdn.net/detail/t12x3456/6468601
最後更新:2017-04-03 12:53:47