ViewPager 从入门到带你撸个启动页之实战PageTransformer切换动画特效四.docx
- 文档编号:27739665
- 上传时间:2023-07-04
- 格式:DOCX
- 页数:13
- 大小:112.81KB
ViewPager 从入门到带你撸个启动页之实战PageTransformer切换动画特效四.docx
《ViewPager 从入门到带你撸个启动页之实战PageTransformer切换动画特效四.docx》由会员分享,可在线阅读,更多相关《ViewPager 从入门到带你撸个启动页之实战PageTransformer切换动画特效四.docx(13页珍藏版)》请在冰豆网上搜索。
ViewPager从入门到带你撸个启动页之实战PageTransformer切换动画特效四
ViewPager从入门到带你撸个启动页之实战PageTransformer切换动画特效(四)
一、ViewPager概述
通过前三篇的分享,我们已经非常熟悉ViewPager的基本使用了,而本篇我们将利用官方提供PageTransformer接口来实现ViewPager个性化的动画切换特效。
Android从3.0开始,google官方新增了属性动画,而ViewPager也新增了ViewPager.PageTransformer接口,我们可以通过这个接口来实现非常不错动画切换效果,Google官网也给我们提供了两个动画例子:
DepthPageTransformer和ZoomOutPageTransformer。
下面我们先来看看这两个动画效果:
ZoomOutPageTransformer动画效果如下:
看起来还是相当不错滴,实际上我们也可以通过ViewPager.PageTransformer接口实现来做出完全不同的切换动画效果,接下来我们就先来介绍一下这个接口。
二、理解ViewPager.PageTransformer
我们先来看看ViewPager.PageTransformer的源码
/**
*APageTransformerisinvokedwheneveravisible/attachedpageisscrolled.
*Thisoffersanopportunityfortheapplicationtoapplyacustomtransformation
*tothepageviewsusinganimationproperties.
*
*
AspropertyanimationisonlysupportedasofAndroid3.0andforward,
*settingaPageTransformeronaViewPageronearlierplatformversionswill
*beignored.
*/
publicinterfacePageTransformer{
/**
*Applyapropertytransformationtothegivenpage.
*
*@parampageApplythetransformationtothispage
*@parampositionPositionofpagerelativetothecurrentfront-and-center
*positionofthepager.0isfrontandcenter.1isonefull
*pagepositiontotheright,and-1isonepagepositiontotheleft.
*/
publicvoidtransformPage(Viewpage,floatposition);
}
其实注释说得很明白,PageTransformer接口将会在页面滑动时被调用,它提供了一个让我们自定义实现ViewPager切换动画的机会,不过该接口实现的动画仅支持android3.0以上的版本,如果在低于android3.0版本上运行,该接口实现的动画将会被忽略,但实际上我们还是有办法在低版本上运行滴,这个后面我们再来讨论。
现在我们在接口中可以看到该接口只有一个transformPage(Viewpage,floatposition)方法,而我们所要关注的也就是这个方法而已,对它传递的两个参数的理解是实现我们动画的关键。
我们就来看看这两个参数代表什么意思。
Viewpage:
这个当然就是我们在ViewPager中滑动的界面。
floatposition:
这个参数是个重点,我们必须好好理解,请注意这个参数是一个float类型,而不是平常我们所理解的int位置。
当position=-1时,表示当前页的前一页,此时该页面是看不见的
当position=0时,表示当前页,当前显示页
当position=1时,表示当前页的下一页
position取值为[-Infinity,-1)->页面不可见
position取值为(1,+Infinity]->页面不可见
position取值为[-1,1]->于可见状态区间
如果前一页和下一页基本各在屏幕占一半时,前一页的position是-0.5,后一页的posiotn是0.5,所以根据position的值我们就可以自行设置需要的alpha,x/y信息
到此,我们对PageTransformer接口就有比较清晰的了解了,下面我们看看官方给我的实现案例。
三、官方的动画案例的应用
publicclassZoomOutPageTransformerimplementsViewPager.PageTransformer{
privatestaticfinalfloatMIN_SCALE=0.85f;
privatestaticfinalfloatMIN_ALPHA=0.5f;
publicvoidtransformPage(Viewview,floatposition){
intpageWidth=view.getWidth();
intpageHeight=view.getHeight();
if(position<-1){//[-Infinity,-1)不可见状态
//Thispageiswayoff-screentotheleft.
view.setAlpha(0);透明度设置为0
}elseif(position<=1){//[-1,1]可见状态,设置动画效果
//Modifythedefaultslidetransitiontoshrinkthepageaswell
floatscaleFactor=Math.max(MIN_SCALE,1-Math.abs(position));
floatvertMargin=pageHeight*(1-scaleFactor)/2;
floathorzMargin=pageWidth*(1-scaleFactor)/2;
if(position<0){
view.setTranslationX(horzMargin-vertMargin/2);
}else{
view.setTranslationX(-horzMargin+vertMargin/2);
}
//Scalethepagedown(betweenMIN_SCALEand1)
view.setScaleX(scaleFactor);
view.setScaleY(scaleFactor);
//Fadethepagerelativetoitssize.
view.setAlpha(MIN_ALPHA+
(scaleFactor-MIN_SCALE)/
(1-MIN_SCALE)*(1-MIN_ALPHA));
}else{//(1,+Infinity]不可见状态
//Thispageiswayoff-screentotheright.
view.setAlpha(0);
}
}
}
我们新建一个ViewPager并应用该动画特效,来看看其实现效果,MainActivity代码如下:
packagecom.zejian.viewpageranimation;
importandroid.app.Activity;
importandroid.os.Bundle;
importandroid.support.v4.view.PagerAdapter;
importandroid.support.v4.view.ViewPager;
importandroid.view.View;
importandroid.view.ViewGroup;
importandroid.view.Window;
importandroid.widget.ImageView;
importjava.util.ArrayList;
importjava.util.List;
publicclassMainActivityextendsActivity{
privateViewPagervp;
privateList
@Override
protectedvoidonCreate(BundlesavedInstanceState){
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_main);
vp=(ViewPager)findViewById(R.id.vp);
initData();
}
publicvoidinitData(){
int[]imageResIDs={R.drawable.android_guide_step_1,R.drawable.android_guide_step_2,
R.drawable.android_guide_step_3};
imageViewList=newArrayList<>();
ImageViewiv;//图片
for(inti=0;i iv=newIeView(this); iv.setScaleType(ImageView.ScaleType.CENTER); iv.setBackgroundResource(imageResIDs[i]); imageViewList.add(iv); } vp.setAdapter(newMyPagerAdapter()); vp.setPageTransformer(true,newZoomOutPageTransformer()); } classMyPagerAdapterextendsPagerAdapter{ @Override publicintgetCount(){ returnimageViewList.size(); } @Override publicbooleanisViewFromObject(Viewview,Objectobject){ returnview==object; } @Override publicvoiddestroyItem(ViewGroupcontainer,intposition,Objectobject){ container.removeView(imageViewList.get(position)); } @Override publicObjectinstantiateItem(ViewGroupcontainer,intposition){ container.addView(imageViewList.get(position)); returnimageViewList.get(position); } } } 代码比较简单,这里就不过多说明了。 有点要提示一下的我们通过如下代码设置ViewPager的动画: vp.setPageTransformer(true,newZoomOutPageTransformer()); 第一个参数表示是否反序画出图片,truechild倒序,falsechild顺序;实际并没有发现什么特别的效果。 第二个参数就是实现动画的类。 下面我们运行程序看看效果: 至于ZoomOutPageTransformer实现类,只要理解position就行了,其余就是如何设置动画而已,在这里就不过多分析了,毕竟动画不是本节重点哈。 我们继续看看官方提供的另一个实现类DepthPageTransformer,代码如下: publicclassDepthPageTransformerimplementsViewPager.PageTransformer{ privatestaticfinalfloatMIN_SCALE=0.75f; publicvoidtransformPage(Viewview,floatposition){ intpageWidth=view.getWidth(); if(position<-1){//[-Infinity,-1) //Thispageiswayoff-screentotheleft. view.setAlpha(0); }elseif(position<=0){//[-1,0] //Usethedefaultslidetransitionwhenmovingtotheleftpage view.setAlpha (1); view.setTranslationX(0); view.setScaleX (1); view.setScaleY (1); }elseif(position<=1){//(0,1] //Fadethepageout. view.setAlpha(1-position); //Counteractthedefaultslidetransition view.setTranslationX(pageWidth*-position); //Scalethepagedown(betweenMIN_SCALEand1) floatFactor=MIN_SCALE +(1-MIN_SCALE)*(1-Math.abs(position)); view.setScaleX(scaleFactor); view.setScaleY(scaleFactor); }else{//(1,+Infinity] //Thispageiswayoff-screentotheright. view.setAlpha(0); } } } 到此,ViewPager.PageTransformer实现与应用就分享完啦。 下面我们再来解决ViewPager切换动画在低版本运行的问题 四、解决ViewPager切换动画在低版本运行的问题 根据google官方给出的例子中,代码中View的动画使用的是属性动画,而属性动画是3.0才新增的特性,所以上面的动画肯定不兼容android3.0以下的版本,这时为解决这个问题,我们就必须引入nineoldandroids了,使用这个开源包,我们就可以在低版本上实现属性动画啦。 我们以DepthPageTransformer为例修改后代码如下: packagecom.zejian.viewpageranimation; importandroid.annotation.TargetApi; importandroid.os.Build; importandroid.support.v4.view.ViewPager; importandroid.view.View; importcom.nineoldandroids.view.ViewHelper; /** *Createdbyzejian *Time16/8/9. *Description: */ publicclassDepthPageTransformerimplementsViewPager.PageTransformer{ privatestaticfinalfloatMIN_SCALE=0.75f; @TargetApi(Build.VERSION_CODES.HONEYCOMB) publicvoidtransformPage(Viewview,floatposition){ intpageWidth=view.getWidth(); if(position<-1){//[-Infinity,-1) //Thispageiswayoff-screentotheleft. //Alpha(0); ViewHelper.setAlpha(view,0); }elseif(position<=0){//[-1,0] //Usethedefaultslidetransitionwhenmovingtotheleftpage //view.setAlpha (1); //view.setTranslationX(0); //view.setScaleX (1); //view.setScaleY (1); ViewHelper.setAlpha(view,1); ViewHelper.setTranslationX(view,0); ViewHelper.setScaleX(view,1); ViewHelper.setScaleY(view,1); }elseif(position<=1){//(0,1] //Fadethepageout. //view.setAlpha(1-position); ViewHelper.setAlpha(view,1-position); //Counteractthedefaultslidetransition //view.setTranslationX(pageWidth*-position); ViewHelper.setTranslationX(view,pageWidth*-position); //Scalethepagedown(betweenMIN_SCALEand1) floatscaleFactor=MIN_SCALE +(1-MIN_SCALE)*(1-Math.abs(position)); //view.setScaleX(scaleFactor); //view.setScaleY(scaleFactor); ViewHelper.setScaleX(view,scaleFactor); ViewHelper.setScaleY(view,scaleFactor); }else{//(1,+Infinity] //Thispageiswayoff-screentotheright. //view.setAlpha(0); ViewHelper.setAlpha(view,0); } } } 这样的话动画是没问题的了,不过在低版本要跑起来我们还必须修改一下ViewPager的源码,我们先来看看vp.setPageTransformer(true,newDepthPageTransformer());的源码: publicvoidsetPageTransformer(booleanreverseDrawingOrder,PageTransformertransformer){ if(Build.VERSION.SDK_INT>=11){ finalbooleanhasTransformer=transformer! =null; finalbooleanneedsPopulate=hasTransformer! =(mPageTransformer! =null); mPageTransformer=transformer; setChildrenDrawingOrderEnabledCompat(hasTransformer); if(hasTransformer){ mDrawingOrder=reverseDrawingOrder? DRAW_ORDER_REVERSE: DRAW_ORDER_FORWARD; }else{ mDrawingOrder=DRAW_ORDER_DEFAULT; } if(needsPopulate)populate(); } } 很显然,ViewPager内部代码if(Build.VERSION.SDK_INT>=11)对版本进行了判断,只有API11以上才生效,所以我们只能去重写一下这个方法。 我们将ViewPager的源码拷贝一份至我们的项目中,我们这里改名为CompatibleViewPager,注释掉版本判断的语句即可,如下: publicvoidsetPageTransformer(booleanreverseDrawingOrder,ViewPager.PageTransformertransformer){ //if(Build.VERSION.SDK_INT>=11) //{ finalbooleanhasTransformer=transformer! =null; finalbooleanneedsPopulate=hasTransformer! =(mPageTransformer! =null); mPageTransformer=sformer; setChildrenDrawingOrderEnabledCompat(hasTransformer); if(hasTransformer){ mDrawingOrder=reverseDrawingOrder? DRAW_ORDER_REVERSE: DRAW_ORDER_FORWARD; }else{ mDrawingOrder=DRAW_ORDER_DEFAULT; } if(needsPopulate)populate
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- ViewPager 从入门到带你撸个启动页之实战PageTransformer切换动画特效四 入门 启动 实战 PageTransformer 切换 动画 特效
链接地址:https://www.bdocx.com/doc/27739665.html