时下盛行的3D动画和2维动画你更鹿晗喜欢看的动画片那1种?为何?

 ›  › 
ViewPager动画的实现原理
前言前两天看到鲍永章分享的以及农民伯伯分享的 文章,都是通过ViewPager来实现酷炫的动画,而现在的App中ViewPager的动画使用也非常的广泛。正好最近一直研究动画,那么就趁热打铁,分析一下相关的开源库吧。本篇文章介绍的ViewPager动画,可以分为两类,第一类是针对于ViewPager的界面滑动动画(这个是PageTransformer的
真正用途),分析并比较了AndroidImageSlider和JazzyViewPager两种实现,第二类是对ViewPager中的内容进行动画
处理,这个是这个是PageTransformer的巧妙应用,处理好了可以达到很棒的交互效果,示例是Yahoo天气的视差效果。ViewPager动画的实现原理从3.0开始,ViewPager开始支持自定义切换动画,暴露的接口为PageTransformer,因此只要实现PageTransformer接口和其唯一的方法transformPage(View view, float position)即可。/**
*&A&PageTransformer&is&invoked&whenever&a&visible/attached&page&is&scrolled.
*&This&offers&an&opportunity&for&the&application&to&apply&a&custom&transformation
*&to&the&page&views&using&animation&properties.
*&&p&As&property&animation&is&only&supported&as&of&Android&3.0&and&forward,
*&setting&a&PageTransformer&on&a&ViewPager&on&earlier&platform&versions&will
*&be&ignored.&/p&
public&interface&PageTransformer&{
*&Apply&a&property&transformation&to&the&given&page.
*&@param&page&Apply&the&transformation&to&this&page
*&@param&position&Position&of&page&relative&to&the¤t&front-and-center
*&position&of&the&pager.&0&is&front&and¢er.&1&is&one&full
*&page&position&to&the&right,&and&-1&is&one&page&position&to&the&left.
public&void&transformPage(View&page,&float&position);
}参数position给定界面的位置相对于屏幕中心的偏移量。在用户滑动界面的时候,是动态变化的。那么我们可以将position的值应用于setAlpha(), setTranslationX(), or setScaleY()方法,从而实现自定义的动画效果。另
外在ViewPager滑动时,内存中存活的Page都会执行transformPage方法,在滑动过程中涉及到两个Page,当前页和下一页,而它们
的position值是相反的(因为是相对运动,一个滑入一个滑出),比如,页面A向右滑动到屏幕一半,页面B也正好处于一半的位置,那么A和B的
position为:0.5 和 -0.5position == &0 :当前界面位于屏幕中心的时候position == &1 :当前Page刚好滑出屏幕右侧position == -1 :当前Page刚好滑出屏幕左侧
AndroidImageSlider动画库解析要说到动画库,肯定会想到代码家,没错,代码家也开源了一个ViewPager效果的库: ,我们就来分析下这个库的实现。AndroidImageSlider除了基本的page动画外,也支持用户为Page内容添加自定义的动画,比如下面描述框的动画。AndroidImageSlider兼容性的实现原理:因为API 11才开始支持PagerTransformer.
这里面修改了Android系统的ViewPager,名为ViewPagerEx,ViewPager里面有一段if逻辑判断是否在3.0以上使用
PagerTransformer。因为PagerTransformer动画效果的实现依赖了PropertyViewAnim。但代码家的这个库使用
NineOldAndroids实现了向3.0之前的兼容。因此就把这个if条件去掉了,其它部分都没变。/**
*&@author&daimajia&:&I&just&remove&the&if&condition&in&setPageTransformer()&to&make&it&compatiable&with&Android&2.0+
*&of&course,&with&the&help&of&the&NineOldDroid.
*&Thanks&to&JakeWharton.
*&/JakeWharton/NineOldAndroids
*/AndroidImageSlider的总体设计BaseTransformer所有Transformer的基类,实现了
ViewPagerEx.PageTransformer接口以及transformPage方法,并提供了onPreTransform(View
view, float position)、onPostTransform(View view, float
position)、onTransform(View view, float position);分别在transformPage前后调用,用来处理为每一次的执行动画前的准备和结束动作,比如还原所有的动画状态。BaseAnimationInterface:ViewPagerEx执行Transformer动画的时候注入一些自己的动画。你需要实现该接口,然后实现以下4个方法,获取SlideView中的View,实现自己的动画。比如底部的DescriptionText动画 出现时的动画就是onNextItemAppear中添加的,你可以点入,看下源码onPrepareCurrentItemLeaveScreen(View current)onPrepareNextItemShowInScreen(View next)onCurrentItemDisappear(View view)onNextItemAppear(View view)而这4个方法的调用是在BaseTransformer中。BaseTransformer统一管理了Page滑动时的所有动画。为了获取这4个方法的调用时机,也是煞费苦心啊,先说下思路:因为ViewPager滑动的时候transformPage方法是实时调用的,这里获取最初两次调用时传入的position进行比较。通过一个HashMap&来维护不同pageView的多个position。但这里为了优化,只取前两个position做比较。先判断起始滑动的方向,然后再判断下一次滑动的方向,两次结果作差来判断到底哪个page要离开界面还是进入界面。确定2个界面的4种临界状态:if(mCustomAnimationInterface&!=&null){
&&&&if(h.containsKey(view)&==&false&||&h.get(view).size()&==&1){
&&&&&&&&if(position&&&-1&&&&position&&&1){
&&&&&&&&&&&&if(h.get(view)&==&null){
&&&&&&&&&&&&&&&&h.put(view,new&ArrayList&Float&());//为每个View创建一个List,来存储偏移分数position
&&&&&&&&&&&&}
&&&&&&&&&&&&h.get(view).add(position);//向指定的View中添加偏移分数
&&&&&&&&&&&&if(h.get(view).size()&==&2){
&&&&&&&&&&&&&&&&float&zero&=&h.get(view).get(0);
&&&&&&&&&&&&&&&&float&cha&=&h.get(view).get(1)&-&h.get(view).get(0);//当前滑动的位移偏移量分数差:&newfraction&-&oldfraction
&&&&&&&&&&&&&&&&if(zero&&&0){//起始时,向左滑动,当前Page中心位于屏幕中心左侧
&&&&&&&&&&&&&&&&&&&&//判断滑动趋势,如果继续向左侧滑动,position从0到1越来越大&newfraction&& oldfraction
&&&&&&&&&&&&&&&&&&&&if(cha&&&-1&&&&cha&&&0){//向右侧滑动
&&&&&&&&&&&&&&&&&&&&&&&&//in
&&&&&&&&&&&&&&&&&&&&&&&&mCustomAnimationInterface.onPrepareNextItemShowInScreen(view);//下一个Page将要进入屏幕
&&&&&&&&&&&&&&&&&&&&}else{//cha&&&0&继续向左侧滑动
&&&&&&&&&&&&&&&&&&&&&&&&//out
&&&&&&&&&&&&&&&&&&&&&&&&mCustomAnimationInterface.onPrepareCurrentItemLeaveScreen(view);//当前Page将要离开屏幕
&&&&&&&&&&&&&&&&&&&&}
&&&&&&&&&&&&&&&&}else{//起始时,向右滑动,当前Page中心位于屏幕中心右侧
&&&&&&&&&&&&&&&&&&&&//判断滑动趋势,如果继续向右侧滑动,position从0到-1越来越小&newfraction&& oldfraction
&&&&&&&&&&&&&&&&&&&&if(cha&&&-1&&&&cha&&&0){//负值,继续向右滑动,因此当前page将要滑出屏幕
&&&&&&&&&&&&&&&&&&&&&&&&//out
&&&&&&&&&&&&&&&&&&&&&&&&mCustomAnimationInterface.onPrepareCurrentItemLeaveScreen(view);//当前Page将要离开屏幕
&&&&&&&&&&&&&&&&&&&&}else{//向左滑动
&&&&&&&&&&&&&&&&&&&&&&&&//in
&&&&&&&&&&&&&&&&&&&&&&&&mCustomAnimationInterface.onPrepareNextItemShowInScreen(view);//下一个Page将要离开屏幕
&&&&&&&&&&&&&&&&&&&&}
&&&&&&&&&&&&&&&&}
&&&&&&&&&&&&}
boolean&isApp,isD
*&Called&each&{@link&#transformPage(View,&float)}&call&after&{@link&#onTransform(View,&float)}&is&finished.
*&@param&view
*&@param&position
protected&void&onPostTransform(View&view,&float&position)&{
&&&&if(mCustomAnimationInterface&!=&null){
&&&&&&&&if(position&==&-1&||&position&==&1){//当前界面刚好完全移除界面
&&&&&&&&&&&&mCustomAnimationInterface.onCurrentItemDisappear(view);
&&&&&&&&&&&&isApp&=&
&&&&&&&&}else&if(position&==&0){
&&&&&&&&&&&&mCustomAnimationInterface.onNextItemAppear(view);//下一个Page刚好完全显示
&&&&&&&&&&&&isDis&=&
&&&&&&&&if(isApp&&&&isDis){
&&&&&&&&&&&&h.clear();
&&&&&&&&&&&&isApp&=&
&&&&&&&&&&&&isDis&=&
}BaseSliderView:该类就是SlideView的基类,持有SlideView的一些公共方法,比如设置
SliderView的image资源的方法image(File
file),图片加载异常和失败的处理,empty(URL)用于展示,errorDisappear(boolean
disappear)。这种思想和一个EmptyView有些类似,在我公司的项目也是使用了这种方式,比如通常一个ListView的界面,会有一个包
装后的progressbar(包含各种情况的处理)来显示进度,当加载失败的时候,或者无数据的时候,可以调用该progressbar身上的方法,去
决定显示何种布局。使用起来很方便。当然如果你的SliderView更复杂,你可以通过实现BaseSliderView,然后实现自己的
SliderView。下面两个类就是切换的View:DefaultSliderView:实现了BaseSliderView,该View默认就是一张图片TextSliderView:带有图片和描述性文字的ViewSliderlayout: &一个控制中心,将InfiniteViewPager,PageIndicator,粘合在一起,控制动画的样式,ViewPager轮循的播放。addSlider:向ViewPager中添加一个SlideViewstartAutoCycle:启动轮播pauseAutoCycle:停止轮播setDuration: 轮播间隔setPagerTransformer 为ViewPager设置自定义的PageTransformeronInterceptTouchEvent 在用户手势按下的时候,就停止轮循Note:这里在onInterceptTouchEvent中处理而不能再onTouchEvent中处理。因为SlideView会消费掉点击事件,事件被消费了,没法返回给SlideLayout的onTouchEvent中。OK,总体设计弄清楚后,剩下来就是动画中最核心的部分了,就是动画效果的实现,这里只简单的介绍Accordion动画的实现,其它的大家可以自己分析。关于PropertyView动画的使用,可以参考我的另一篇文章:Accordionpublic&class&AccordionTransformer&extends&BaseTransformer&{
&&&&@Override
&&&&protected&void&onTransform(View&view,&float&position)&{
&&&&&&&&ViewHelper.setPivotX(view,position&&&0&?&0&:&view.getWidth());
&&&&&&&&ViewHelper.setScaleX(view,position&&&0&?&1f&+&position&:&1f&-&position);
}代码家在README中注明了Thanks
JazzyViewPager,开始没注意,后来看JazzyViewPager的源码时候偶然发现AndroidImageSlider的一些实现的灵
感是来自JazzyViewPager项目。不过JazzyViewPager的实现方式略显复杂,没有使用PageTransformer接口,而是使
用了OnPageChangeListener接口的onPageScrolled方法。下面简单的看下JazzyViewPager库的动画实现,它将positionOffset作为参数控制。由于positionOffset的值为[0,1),所以就需要分别处理正负的情况。另外JazzyViewPager是通过维护一个LinkedHashMap来
持有Page的引用。在Adapter添加界面的时候,会调用JazzyViewPager的 setObjectForPosition(Object
obj, int position)
方法存入到集合中去。然后在onPageScrolled方法中再根据position获取当前Page的前一个mLeft和后一个mRight界面,分
别对前后两个界面添加动画。两种方式的关键参数区别onPageScrolled(int position, float positionOffset, int positionOffsetPixels)方法的参数:/**
*&This&method&will&be&invoked&when&the¤t&page&is&scrolled,&either&as&part
*&of&a&programmatically&initiated&smooth&scroll&or&a&user&initiated&touch&scroll.
*&@param&position&Position&index&of&the&first&page¤tly&being&displayed.
*&Page&position+1&will&be&visible&if&positionOffset&is&nonzero.
*&@param&positionOffset&Value&from&[0,&1)&indicating&the&offset&from&the&page&at&position.
*&@param&positionOffsetPixels&Value&in&pixels&indicating&the&offset&from&position.
public&void&onPageScrolled(int&position,&float&positionOffset,&int&positionOffsetPixels);下面是打印的PageTransformer接口的transformPage时position的值:相邻两界面的绝对值的和为1.而正负则表示了滑入和滑出状态12-15&21:03:13.025&I/System.out﹕&transformPage----------------------&-0.
12-15&21:03:13.025&I/System.out﹕&transformPage----------------------&0.5638889
12-15&21:03:13.045&I/System.out﹕&transformPage----------------------&-0.
12-15&21:03:13.045&I/System.out﹕&transformPage----------------------&0.
12-15&21:03:13.045&I/System.out﹕&transformPage----------------------&-0.
12-15&21:03:13.045&I/System.out﹕&transformPage----------------------&0.
12-15&21:03:13.055&I/System.out﹕&transformPage----------------------&-0.
12-15&21:03:13.055&I/System.out﹕&transformPage----------------------&0.
12-15&21:03:13.065&I/System.out﹕&transformPage----------------------&-0.
12-15&21:03:13.065&I/System.out﹕&transformPage----------------------&0.
12-15&21:03:13.075&I/System.out﹕&transformPage----------------------&-0.
12-15&21:03:13.075&I/System.out﹕&transformPage----------------------&0.onPageScrolled方法的positionOffset的值为 [0, 1)
,而PageTransformer接口的transformPage(View page, float position)
已经标好了正负值(滑入和滑出),如果你的动画正好是相对的,那么用transfromPage就简单的多。我们取同一种动画效果Cube来比较一下JazzyViewPager和AndroidImageSlider两者的实现:JazzyViewPager部分源码@Override
public&void&onPageScrolled(int&position,&float&positionOffset,&int&positionOffsetPixels)&{
&&&&float&effectOffset&=&isSmall(positionOffset)&?&0&:&positionO
&&&&mLeft&=&findViewFromObject(position);
&&&&mRight&=&findViewFromObject(position+1);
&&&&switch&(mEffect)&{
&&&&&&&&case&Standard:
&&&&&&&&...
&&&&&&&&case&animateCube:
&&&&&&&&animateCube(mLeft,&mRight,&effectOffset);
private&void&animateCube(View&left,&View&right,&float&positionOffset,&boolean&in)&{
&&&&if&(mState&!=&State.IDLE)&{
&&&&&&&&if&(left&!=&null)&{
&&&&&&&&&&&&manageLayer(left,&true);
&&&&&&&&&&&&mRot&=&(in&?&90.0f&:&-90.0f)&*&positionO
&&&&&&&&&&&&ViewHelper.setPivotX(left,&left.getMeasuredWidth());
&&&&&&&&&&&&ViewHelper.setPivotY(left,&left.getMeasuredHeight()*0.5f);
&&&&&&&&&&&&ViewHelper.setRotationY(left,&mRot);
&&&&&&&&if&(right&!=&null)&{
&&&&&&&&&&&&manageLayer(right,&true);
&&&&&&&&&&&&mRot&=&-(in&?&90.0f&:&-90.0f)&*&(1-positionOffset);
&&&&&&&&&&&&ViewHelper.setPivotX(right,&0);
&&&&&&&&&&&&ViewHelper.setPivotY(right,&right.getMeasuredHeight()*0.5f);
&&&&&&&&&&&&ViewHelper.setRotationY(right,&mRot);
public&void&setObjectForPosition(Object&obj,&int&position)&{//每次Adapter实例化View的时候,调用该方法,将实例化的View存入集合
&&&&mObjs.put(Integer.valueOf(position),&obj);
public&View&findViewFromObject(int&position)&{//根据position从集合中获取到对应的View
&&&&Object&o&=&mObjs.get(Integer.valueOf(position));
&&&&if&(o&==&null)&{
&&&&&&&&return&
&&&&PagerAdapter&a&=&getAdapter();
&&&&View&v;
&&&&for&(int&i&=&0;&i&&&getChildCount();&i++)&{
&&&&&&&&v&=&getChildAt(i);
&&&&&&&&if&(a.isViewFromObject(v,&o))
&&&&&&&&return&v;
&&&&return&
}AndroidIamgeSlider中的CubeIn:public&class&CubeInTransformer&extends&BaseTransformer&{
&&&&@Override
&&&&protected&void&onTransform(View&view,&float&position)&{
&&&&&&&&//&Rotate&the&fragment&on&the&left&or&right&edge
&&&&&&&&ViewHelper.setPivotX(view,position&&&0&?&0&:&view.getWidth());
&&&&&&&&ViewHelper.setPivotY(view,0);
&&&&&&&&ViewHelper.setRotation(view,-90f&*&position);
}JazzyViewPager:CubeIn上面代码中已经贴出:if&(left&!=&null)&{
&&&&mRot&=&(in&?&90.0f&:&-90.0f)&*&positionO
if&(right&!=&null)&{
&&&&mRot&=&-(in&?&90.0f&:&-90.0f)&*&(1-positionOffset);
}可以精简为:positionOffset&*&value
-(1-positionOffset)&*&value与从上面的transformPage打印的position的值再比较下12-15&21:03:13.075&I/System.out﹕&transformPage----------------------&-0.
12-15&21:03:13.075&I/System.out﹕&transformPage----------------------&0.结论:发现transformPage已经帮我们处理好了一切,直接用。我们可以根据正负符号来判断滑
入和滑出的View(不用像JazzyViewPager那样去维护一个集合了),从而针对滑入滑出做出不同或相对的的动画。最简单的,两个界面如果是简
单的相对动画(滑入对滑出),则什么都不用处理,直接用就行了,就像下面介绍的Yahoo视差的实现一样,具体可以看下面的讲解。大家仔细看下相同的动画效果的处理方式,CubeInTransformer不用单独处理上一个和下一个界面,而只管根据position的正负判断当前Page和下一个Page去自定义不同的动画即可。所以可以把AndroidImageSlider中的一些动画效果看做是JazzyViewPager的精简版本。对于ViewPager如何帮我们处理View的呢?可以看下源码:&protected&void&onPageScrolled(int&position,&float&offset,&int&offsetPixels)&{
&&&&if&(mPageTransformer&!=&null)&{
&&&&&&&&final&int&scrollX&=&getScrollX();
&&&&&&&&final&int&childCount&=&getChildCount();
&&&&&&&&for&(int&i&=&0;&i&&&childC&i++)&{
&&&&&&&&&&&&final&View&child&=&getChildAt(i);
&&&&&&&&&&&&final&LayoutParams&lp&=&(LayoutParams)&child.getLayoutParams();
&&&&&&&&&&&&if&(lp.isDecor)&
&&&&&&&&&&&&final&float&transformPos&=&(float)&(child.getLeft()&-&scrollX)&/&getClientWidth();
&&&&&&&&&&&&mPageTransformer.transformPage(child,&transformPos);
}小结上面主要介绍了ViewPager的Page的滑动动画,两种实现方式:PageTransformer.transformPage方式:在执行onPageScrolled方法的时候,会遍历ViewPager的所有View,并执行其transformPage方法。position是已经处理好的(方向和值)onPageScrolled
方式:略显复杂,因为没法拿到View,还要自己去维护一个View集合,并且positionOffset的限制,需要自己去处理不同View的
position : &PageA:position , PageB:-(1-position)。为ViewPager的Page内容添加动画,实现炫酷的交互效果Tholotis实现原理:为Page内部的View处理不同的平移速度,达到视差的效果,作者的代码:public&void&transformPage(View&view,&float&position)&{
&&&&int&pageWidth&=&view.getWidth();
&&&&if&(position&&&-1)&{&//&[-Infinity,-1)
&&&&&&&&//&This&page&is&way&off-screen&to&the&left.
&&&&&&&&view.setAlpha(0);
&&&&}&else&if&(position&&=&1)&{&//&[-1,1]
&&&&&&&&mBlur.setTranslationX((float)&(-(1&-&position)&*&0.5&*&pageWidth));
&&&&&&&&mBlurLabel.setTranslationX((float)&(-(1&-&position)&*&0.5&*&pageWidth));
&&&&&&&&mDim.setTranslationX((float)&(-(1&-&position)&*&pageWidth));
&&&&&&&&mDimLabel.setTranslationX((float)&(-(1&-&position)&*&pageWidth));
&&&&&&&&mCheck.setTranslationX((float)&(-(1&-&position)&*&1.5&*&pageWidth));
&&&&&&&&mDoneButton.setTranslationX((float)&(-(1&-&position)&*&1.7&*&pageWidth));
&&&&&&&&//&The&0.5,&1.5,&1.7&values&you&see&here&are&what&makes&the&view&move&in&a&different&speed.
&&&&&&&&//&The&bigger&the&number,&the&faster&the&view&will&translate.
&&&&&&&&//&The&result&float&is&preceded&by&a&minus&because&the&views&travel&in&the&opposite&direction&of&the&movement.
&&&&&&&&mFirstColor.setTranslationX((position)&*&(pageWidth&/&4));
&&&&&&&&mSecondColor.setTranslationX((position)&*&(pageWidth&/&1));
&&&&&&&&mTint.setTranslationX((position)&*&(pageWidth&/&2));
&&&&&&&&mDesaturate.setTranslationX((position)&*&(pageWidth&/&1));
&&&&&&&&//&This&is&another&way&to&do&it
&&&&}&else&{&//&(1,+Infinity]
&&&&&&&&//&This&page&is&way&off-screen&to&the&right.
&&&&&&&&view.setAlpha(0);
}GitHub上类似的效果还有:这两个项目都封装成了库,使用的时候也简单,但一般我们可以通过ViewPager.PageTransformer来实现这样的效果,从上面
AndroidImageSlider与JazzyViewPager的对比中也能看到,PageTransformer的实现方式更简单。而且
ViewPager的动画库也很多,比如上面的JazzyViewPager。你只需把某一个动画效果的transformPage方法的逻辑拿来就可
用,当然如果你的需求更复杂,或者ViewPager实现起来较麻烦,你可以考虑上面的两个项目,扩展自己的思维。JazzyViewPager:Yahoo天气原理很简单,只是这次处理的动画对象是背景图片,减慢其平移的速度,而ViewPager的内容正常移动,从而达到视差的效果。public&class&ParallaxPageTransformer&implements&ViewPager.PageTransformer&{
&&&&public&void&transformPage(View&view,&float&position)&{
&&&&&&&&int&pageWidth&=&view.getWidth();
&&&&&&&&if&(position&&&-1)&{&//&[-Infinity,-1)
&&&&&&&&&&&&//&This&page&is&way&off-screen&to&the&left.
&&&&&&&&&&&&view.setAlpha(1);
&&&&&&&&}&else&if&(position&&=&1)&{&//&[-1,1]
&&&&&&&&&&&&dummyImageView.setTranslationX(-position&*&(pageWidth&/&2));&//Half&the&normal&speed
&&&&&&&&}&else&{&//&(1,+Infinity]
&&&&&&&&&&&&//&This&page&is&way&off-screen&to&the&right.
&&&&&&&&&&&&view.setAlpha(1);
}OK,本来想自己写,但刚巧在GitHub上发现了一个: ,并提供了 ,实现了Yahoo天气的效果,但多了一些缩放的效果,将缩放的代码注释掉就和Yahoo天气的效果完全一样了。另外想clone到本地的朋友注意了,由于作者的AndroidStudio版本太老,导入的时候你需要做一些处理。作者把该Transformer抽取出来,做为了一个lib,就一个类,核心代码很简单,说明ViewPager.PageTransformer接口很强大啊:@Override
public&void&transformPage(View&view,&float&position)&{
&&&&View¶llaxView&=&view.findViewById(id);
&&&&if&(parallaxView&!=&null)&{
&&&&&&&&if&(position&&&-1&&&&position&&&1)&{
&&&&&&&&&&&&float&width&=¶llaxView.getWidth();
&&&&&&&&&&&¶llaxView.setTranslationX(-(position&*&width&*&speed));
&&&&&&&&&&&&float&sc&=&((float)view.getWidth()&-&border)/&view.getWidth();
&&&&&&&&&&&&if&(position&==&0)&{//这里处理了缩放的效果,去掉即和Yahoo天气的效果一样
&&&&&&&&&&&&&&&&view.setScaleX(1);
&&&&&&&&&&&&&&&&view.setScaleY(1);
&&&&&&&&&&&&}&else&{
&&&&&&&&&&&&&&&&view.setScaleX(sc);
&&&&&&&&&&&&&&&&view.setScaleY(sc);
&&&&&&&&&&&&}
}看了上面的实现,大家应该知道如何去实现类似的交互动画了,而且现在的App导航页中,也越来越多的使用到了这样的交互,作者在文章还列举了News
Digest的导航页,有了思路,实现起来应该就不难了,第一、三页的动画上面已经介绍过,对于第二页,其实就是一个旋转动画。实时的旋转可以通过实时变
化的position来处理。类似的项目:总结:整篇文章介绍的东西其实很简单,只是以前没有研究过ViewPager.PageTransformer,使用简单,但功能强大,position
参数在动画处理中相当重要,因为是实时的百分比,所以省去了自己不少计算,如果你需要为ViewPager自定义动画,那么选择
PageTransformer,对于本文的第二类巧妙动画效果的介绍,看具体情况决定是否使用PageTransformer,如果position能
很方便帮助动画的计算,那是最好的,如果不是那么你完全可以使用onPageScrolled来处理,源码中也可看到,PageTransformer就
是在onPageScroll中调用的。使用时要注意,它只支持3.0以上的系统。如果要兼容,可以参考上面
AndroidImageSlider的兼容实现。在文章中也插入了不少ViewPager动画项目的链接,也许不是使用
PageTransformer,但也是一种思路的扩展,供大家参考。下一篇文章,我会介绍Fragment的动画,大家敬请期待。参考文献: GitHub上相关的ViewPager动画的项目轮循的ViewPagerVerticalViewPager特效的ViewPager与ViewPager一起使用的导航: (不支持TextView颜色的变化) (支持TextView颜色变化) FragmentAnim
上一篇: 这篇文章是对n Android 5.0 中Activity Fragment transition API的一个总体回顾,这是关于transition系列文章的第一篇。 Part 1: Getting Started with Activity Fragment Transitions Part 2: Content Transitions In-Depth Part 3a: Shared Element Transi
下一篇: 在阅读本文之前需要对transitioning view这个概念有一定认识,他专指content transition中会发生变换的view - 译者注 本文将对content transition以及其在Activity和Fragment Transition API中扮演的角色做一个深入分析。这是此话题系列的第二章节: 第一章:

参考资料

 

随机推荐