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 plain copy
  1. <com.jfeinstein.jazzyviewpager.JazzyViewPager  
  2.     xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     xmlns:app="http://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中的的枚举类:

[java]  view plain copy
  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.     }  

怎么设置呢?非常简单:

[java]  view plain copy
  1. private JazzyViewPager mJazzy;  
  2. /* ... */  
  3. mJazzy.setTransitionEffect(TransitionEffect.*);  

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


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

TransitionEffect.Tablet

                                   


TransitionEffect.Stack

                                   

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


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

当ViewPager中的子View超过三个的时候,我们需要对PagerAdapter修改,重写InstantiateItem()方法,,会导致补间动画不能正常显示.

EX:

[java]  view plain copy
  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代替.

[java]  view plain copy
  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.增加动画效果的具体实现:

[java]  view plain copy
  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的方法中,增加对应效果的处理:

[java]  view plain copy
  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下载地址:http://download.csdn.net/detail/t12x3456/6468601


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一个简单的示例代码,演示如何使用ViewPager实现广告页轮播、卡片切换和卡片缩放动画。 1. 布局文件 在布局文件中,我们需要添加一个ViewPager控件,并为ViewPager设置相应的布局参数,如下所示: ```xml <androidx.viewpager.widget.ViewPager android:id="@+id/view_pager" android:layout_width="match_parent" android:layout_height="200dp" android:clipToPadding="false" android:paddingLeft="50dp" android:paddingRight="50dp" android:overScrollMode="never"/> ``` 注意,我们在这里设置了ViewPager的clipToPadding属性为false,这是为了让ViewPager的子视图可以超出ViewPager的边界,从而实现卡片切换效果。我们还设置了ViewPager的paddingLeft和paddingRight属性,以便在ViewPager的两侧留出一些空白区域。 2. ViewPager适配器 接下来,我们需要创建一个ViewPager适配器,用于管理ViewPager中的视图。在这个适配器中,我们可以根据需要添加或删除ViewPager中的子视图,并为这些子视图设置相应的布局参数和动画效果。 ```java public class ViewPagerAdapter extends PagerAdapter { private Context mContext; private List<Integer> mImageIds; public ViewPagerAdapter(Context context, List<Integer> imageIds) { mContext = context; mImageIds = imageIds; } @Override public int getCount() { return mImageIds.size(); } @Override public boolean isViewFromObject(@NonNull View view, @NonNull Object object) { return view == object; } @NonNull @Override public Object instantiateItem(@NonNull ViewGroup container, int position) { ImageView imageView = new ImageView(mContext); imageView.setImageResource(mImageIds.get(position)); imageView.setScaleType(ImageView.ScaleType.CENTER_CROP); // 添加缩放动画效果 if (position == 0) { imageView.setScaleX(1.2f); imageView.setScaleY(1.2f); } else { imageView.setScaleX(1.0f); imageView.setScaleY(1.0f); } container.addView(imageView); return imageView; } @Override public void destroyItem(@NonNull ViewGroup container, int position, @NonNull Object object) { container.removeView((View) object); } } ``` 在这个适配器中,我们需要重写一些方法: - getCount():返回ViewPager中子视图的数量。 - isViewFromObject():判断一个视图是否是由给定的对象生成的。 - instantiateItem():当一个视图需要被添加到ViewPager中时,会调用这个方法来创建这个视图,并将它添加到ViewPager中。 - destroyItem():当一个视图需要被从ViewPager中删除时,会调用这个方法来删除这个视图。 在instantiateItem()方法中,我们为每个子视图设置了一个默认的缩放比例,同时也可以根据需要设置子视图的其他动画效果。 3. 设置ViewPager的滑动效果 为了让ViewPager的滑动效果更加流畅,我们可以为ViewPager设置一些滑动效果参数: ```java viewPager.setClipToPadding(false); viewPager.setPadding(50, 0, 50, 0); viewPager.setPageMargin(20); viewPager.setOffscreenPageLimit(3); viewPager.setPageTransformer(true, new ViewPager.PageTransformer() { @Override public void transformPage(@NonNull View page, float position) { float scale = 1 - Math.abs(position) * 0.2f; page.setScaleX(scale); page.setScaleY(scale); } }); ``` 在这里,我们设置了ViewPager的clipToPadding属性为false,同时设置了ViewPager的padding属性和pageMargin属性,以便在ViewPager的两侧留出一些空白区域,并为ViewPager中的子视图之间添加一些间隔。我们还设置了ViewPager的offscreenPageLimit属性,以便预加载一些子视图,以提高滑动效果的流畅度。 最后,我们为ViewPager设置了一个PageTransformer,这个PageTransformer可以为ViewPager中的每个子视图设置一个动画效果。在这里,我们为每个子视图设置了一个缩放效果,使得ViewPager中的子视图在滑动过程中可以自动缩放。 4. 加载ViewPager 在Activity或Fragment中,我们只需要创建一个ViewPagerAdapter对象,并将这个适配器设置到ViewPager中即可: ```java List<Integer> imageIds = new ArrayList<>(); imageIds.add(R.drawable.advertisement1); imageIds.add(R.drawable.advertisement2); imageIds.add(R.drawable.advertisement3); ViewPagerAdapter adapter = new ViewPagerAdapter(getContext(), imageIds); ViewPager viewPager = findViewById(R.id.view_pager); viewPager.setAdapter(adapter); ``` 这样,就可以完成Android中使用ViewPager实现广告页轮播、卡片切换和卡片缩放动画的代码了。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值