Android 深入ViewPager补间动画,实现类京东商城首页广告Banner切换效果

某天看到京东商城首页的滑动广告的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="http://schemas.android.com/apk/res/android" 
    xmlns:app="http://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下载地址:http://download.csdn.net/detail/t12x3456/6468601

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏CRPER折腾记

Angular 2 + 折腾记 :(6) 动手实现只有年月的小组件

这个组件实现并不是很复杂,我会尽量注释; 这货诞生的理由就是项目刚好有一个地方必须只能选择年月,而github上ng2+日期组件都涉及到年月日或时分秒; 效果用...

921
来自专栏韩东吉的Unity杂货铺

零基础入门 20: UGUI DropDown

(题外话,因为这期分享中段制作之后,微信平台抽疯,Gif图无法使用,导致我不得不尝试用其他的方式来让文章看起来没那么死板,在后面的部分展示中,我插入了视频文件而...

3094
来自专栏Android 技术栈

Android 关于WebView全方面的使用(项目应用篇)

WebView的使用已经是老生常谈了,看到很多文章说了用法,但我很少看到全的或者是项目中可以直接使用的,都是看了很多后,自己把功能都集合在一起。这里是一份比较全...

2104
来自专栏技术总结

Photos存储、获取、更改照片详解

2609
来自专栏听雨堂

从MapX到MapXtreme2004[2]-图层操作

Mapx中基本的图层操作还是比较简单的,集中在对Layers和Layer的处理上,对别的没有太多要求。   在MapXtreme中,要完成类似功能,发生了一点...

2138
来自专栏我有一个梦想

Python 项目实践一(外星人入侵小游戏)第三篇

接着上节的继续学习, 一 重构:模块game_functions 在大型项目中,经常需要在添加新代码前重构既有代码。重构旨在简化既有代码的结构,使其更容易扩展。...

3259
来自专栏君赏技术博客

百思不得姐数据挖掘第三篇

播放视频的界面现在只剩下视频的功能了,对于这种播放视频的应该属于功能块。我们可以单独把这个功能提取出来。

1312
来自专栏向治洪

MobX 在 React Native开发中的应用

MobX 是一款精准的状态管理工具库,如果你在 React 和 React Native 应用中使用过 Flux、Alt、Redux 和 Reflux,那毫不犹...

2637
来自专栏林德熙的博客

win10 uwp 萤火虫效果 安装 win2d创建界面后台的方法核心代码

本文在Nukepayload2指导下,使用他的思想用C#写出来。 本文告诉大家,如何使用 win2d 做出萤火虫效果。

1201
来自专栏携程技术中心

干货 | React Fiber 初探

1842

扫码关注云+社区

领取腾讯云代金券