您的位置:首页 > 移动开发 > Android开发

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

2013-11-01 08:58 966 查看

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.布局文件中遵照自定义控件的写法即可:

[java]
view plaincopyprint?

<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" />  

<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中的的枚举类:

[java]
view plaincopyprint?

public enum TransitionEffect {  
        Standard,  
        Tablet,  
        CubeIn,  
        CubeOut,  
        FlipVertical,  
        FlipHorizontal,  
        Stack,  
        ZoomIn,  
        ZoomOut,  
        RotateUp,  
        RotateDown,  
        Accordion  
    }  

public enum TransitionEffect {
        Standard,
        Tablet,
        CubeIn,
        CubeOut,
        FlipVertical,
        FlipHorizontal,
        Stack,
        ZoomIn,
        ZoomOut,
        RotateUp,
        RotateDown,
        Accordion
    }


怎么设置呢?非常简单:

[java]
view plaincopyprint?

private JazzyViewPager mJazzy;  
/* ... */  
mJazzy.setTransitionEffect(TransitionEffect.*);  

private JazzyViewPager mJazzy;
/* ... */
mJazzy.setTransitionEffect(TransitionEffect.*);


在京东商城使用的效果即为TransitionEffect.CubeOut

这里我们还可以看一下其他的效果

TransitionEffect.Tablet

                                  


TransitionEffect.Stack

                                  


其他效果大家可以自己尝试下.

3.集成该开源库需要注意一些事项
:


当ViewPager中的子View超过三个的时候,我们需要对
PagerAdapter修改,重写InstantiateItem()方法,如下:




[java]
view plaincopyprint?

private JazzyViewPager mJazzy;  
/* ... */  
@Override  
public Object instantiateItem(ViewGroup container, final int position) {  
    Object obj = super.instantiateItem(container, position);  
    mJazzy.setObjectForPosition(obj, position);  
    return obj;  
}  

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代替.

[java]
view plaincopyprint?

public enum TransitionEffect {  
        Standard,  
        Tablet,  
        CubeIn,  
        CubeOut,  
        FlipVertical,  
        FlipHorizontal,  
        Stack,  
        ZoomIn,  
        ZoomOut,  
        RotateUp,  
        RotateDown,  
        Accordion,  
        <SPAN style="COLOR: #ff0000">Test</SPAN>  
 }  

public enum TransitionEffect {
Standard,
Tablet,
CubeIn,
CubeOut,
FlipVertical,
FlipHorizontal,
Stack,
ZoomIn,
ZoomOut,
RotateUp,
RotateDown,
Accordion,
Test
 }


2.增加动画效果的具体实现:

[java]
view plaincopyprint?

protected void animateTest(View left, View right, float positionOffset) {     
 if (mState != State.IDLE) {  
  if (left != null) {  
   //此处增加具体动画   
 }  
  if (right != null) {  
   //此处增加具体动画实现    
 }  
 }  
}  

protected void animateTest(View left, View right, float positionOffset) {
if (mState != State.IDLE) {
if (left != null) {
//此处增加具体动画
}
if (right != null) {
//此处增加具体动画实现
}
}
}


3.在onPageScrolled的方法中,增加对应效果的处理:

[java]
view plaincopyprint?

@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;  
}  
  
}  

@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;
case Test:
animateTest(mLeft, mRight, effectOffset);
break;
 }

super.onPageScrolled(position, positionOffset, positionOffsetPixels);

if (effectOffset == 0) {
disableHardwareLayer();
mState = State.IDLE;
}

}


经过这三步,我们就可以添加具有新的补间动画的ViewPager. 这里大家可以尽情发挥自己的创意,不断地扩展该开源库,实现自己想要的效果.

Demo下载地址:http://download.csdn.net/detail/t12x3456/6468601

转载自:http://blog.csdn.net/t12x3456/article/details/13290349
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  android开发
相关文章推荐