Android至ViewPager添加切换动画——使用属性动画
转载请注明出处:http://blog.csdn.net/allen315410/article/details/44200623
ViewPager作为Android最经常使用的的组件之中的一个。相信大家在项目中会频繁的使用到的,比如利用ViewPager制作引导页、轮播图,甚至做整个app的表现层的框架等等。
Android3.0下面不支持切换动画
可是在Android 3.0(API 11)下面的ViewPager是比較死板的,不支持动画特效的,这也就让ViewPager在切换的时候达不到非常好的用户体验,下面就是Android3.0下面不加入动画的ViewPager的实现代码以及效果演示:
public class MainActivity extends Activity { private ViewPager mViewPager;
private int[] imgRes = new int[] { R.drawable.guide_image1, R.drawable.guide_image2, R.drawable.guide_image3 };
private List<ImageView> imgList = new ArrayList<ImageView>(); @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_main);
mViewPager = (ViewPager) findViewById(R.id.viewpager);
mViewPager.setAdapter(new PagerAdapter() { @Override
public boolean isViewFromObject(View arg0, Object arg1) {
return arg0 == arg1;
} @Override
public int getCount() {
return imgRes.length;
} @Override
public Object instantiateItem(ViewGroup container, int position) {
ImageView mImageView = new ImageView(MainActivity.this);
mImageView.setBackgroundResource(imgRes[position]);
mImageView.setScaleType(ScaleType.CENTER_CROP);
imgList.add(mImageView);
container.addView(mImageView);
return mImageView;
} @Override
public void destroyItem(ViewGroup container, int position, Object object) {
container.removeView(imgList.get(position));
}
});
}
}
上面是最简单的ViewPager使用的Demo。执行例如以下。看起来非常普通非常死板:
支持Android3.0以上的官方方法
public void setPageTransformer(boolean reverseDrawingOrder, PageTransformer transformer){...}
当中第一个參数boolean类型设置true就好,第二个參数PageTransformer就是我们自己定义好的动画效果:
mViewPager = (ViewPager) findViewById(R.id.viewpager);
mViewPager.setPageTransformer(true, new ZoomOutPageTransformer());
当中ZoomOutPageTransformer的代码来自于google的training文档中,英文好的朋友能够直接进入文档查看,链接是
public class ZoomOutPageTransformer implements ViewPager.PageTransformer {
private static final float MIN_SCALE = 0.85f;
private static final float MIN_ALPHA = 0.5f; public void transformPage(View view, float position) {
int pageWidth = view.getWidth();
int pageHeight = view.getHeight(); if (position < -1) { // [-Infinity,-1)
// This page is way off-screen to the left.
view.setAlpha(0); } else if (position <= 1) { // [-1,1]
// Modify the default slide transition to shrink the page as well
float scaleFactor = Math.max(MIN_SCALE, 1 - Math.abs(position));
float vertMargin = pageHeight * (1 - scaleFactor) / 2;
float horzMargin = pageWidth * (1 - scaleFactor) / 2;
if (position < 0) {
view.setTranslationX(horzMargin - vertMargin / 2);
} else {
view.setTranslationX(-horzMargin + vertMargin / 2);
} // Scale the page down (between MIN_SCALE and 1)
view.setScaleX(scaleFactor);
view.setScaleY(scaleFactor); // Fade the page relative to its size.
view.setAlpha(MIN_ALPHA + (scaleFactor - MIN_SCALE) / (1 - MIN_SCALE) * (1 - MIN_ALPHA)); } else { // (1,+Infinity]
// This page is way off-screen to the right.
view.setAlpha(0);
}
}
}
另外Google文档中还提供了另外一个动画的实现方式,我暂且把源代码附在以下:
public class DepthPageTransformer implements ViewPager.PageTransformer {
private static final float MIN_SCALE = 0.75f; 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 <= 0) { // [-1,0]
// Use the default slide transition when moving to the left page
view.setAlpha(1);
view.setTranslationX(0);
view.setScaleX(1);
view.setScaleY(1); } else if (position <= 1) { // (0,1]
// Fade the page out.
view.setAlpha(1 - position); // Counteract the default slide transition
view.setTranslationX(pageWidth * -position); // Scale the page down (between MIN_SCALE and 1)
float scaleFactor = MIN_SCALE + (1 - MIN_SCALE) * (1 - Math.abs(position));
view.setScaleX(scaleFactor);
view.setScaleY(scaleFactor); } else { // (1,+Infinity]
// This page is way off-screen to the right.
view.setAlpha(0);
}
}
}
两种方式的所实现的效果例如以下所看到的,一是ZoomOutPageTransformer,二是DepthPageTransformer
兼容Android3.0下面的版本号
public class DepthPageTransformer implements ViewPager.PageTransformer {
private static final float MIN_SCALE = 0.75f; public void transformPage(View view, float position) {
int pageWidth = view.getWidth(); if (position < -1) {
// view.setAlpha(0);
ViewHelper.setAlpha(view, 0);
} else if (position <= 0) {
// view.setAlpha(1);
ViewHelper.setAlpha(view, 1);
// view.setTranslationX(0);
ViewHelper.setTranslationX(view, 0);
// view.setScaleX(1);
ViewHelper.setScaleX(view, 1);
// view.setScaleY(1);
ViewHelper.setScaleY(view, 1);
} else if (position <= 1) {
// view.setAlpha(1 - position);
ViewHelper.setAlpha(view, 1 - position);
// view.setTranslationX(pageWidth * -position);
ViewHelper.setTranslationX(view, pageWidth * -position);
float scaleFactor = MIN_SCALE + (1 - MIN_SCALE) * (1 - Math.abs(position));
// view.setScaleX(scaleFactor);
ViewHelper.setScaleX(view, scaleFactor);
// view.setScaleY(scaleFactor);
ViewHelper.setScaleY(view, scaleFactor);
} else {
// view.setAlpha(0);
ViewHelper.setAlpha(view, 0);
}
}
}
为了好理解,我没有将Google提供的源代码删除,而是凝视掉了,方便大家进行比較阅读,然而即使这样使用了NineOldAndroids对我们的动画源代码进行了改造,当我们打开一个Android2.3的模拟器执行一下的时候发现,没有起到效果。也就是这个动画效果并没有执行。在模拟器上执行的ViewPager滑动的效果还是原始默认的左右来回切换的动画。这又是怎么回事呢?为止,我们须要打开ViewPager的源代码进行阅读一下了。既然是在mViewPager.setPageTransformer(true,
new DepthPageTransformer());这句代码没有起到效果。那么我们就点进去查看一下setPageTransformer这种方法的源代码,源代码例如以下:
public void setPageTransformer(boolean reverseDrawingOrder, PageTransformer transformer){
if (Build.VERSION.SDK_INT >= 11) {
boolean hasTransformer = transformer != null;
boolean needsPopulate = hasTransformer != (this.mPageTransformer != null);
this.mPageTransformer = transformer;
setChildrenDrawingOrderEnabledCompat(hasTransformer);
if (hasTransformer) {
this.mDrawingOrder = (reverseDrawingOrder ? 2 : 1);
} else {
this.mDrawingOrder = 0;
}
if (needsPopulate)
populate();
}
}
好了,源代码一目了然,我们分析到在ViewPager中的setPageTransFormer这种方法中。首先推断了一下当前设备的Build.VERSION_SDK_INT>=11,也就是说当前设备是Android3.0以上系统的话,这种方法体运行没问题,可是若是3.0一下,那就抱歉。无法运行了。知道这个原因之后我们就须要解决问题了。我在这里改动了一下ViewPager的源代码,改动ViewPager的源代码之前。读者能够先去下载一份ViewPager的源代码,然后复制到project中,又一次命名一下,将里面的if推断语句给删除了。
下面就是我改动后的部分源代码,命名为ViewPagerCompat:
public void setPageTransformer(boolean reverseDrawingOrder, ViewPager.PageTransformer transformer) {
// if (Build.VERSION.SDK_INT >= 11) {
final boolean hasTransformer = transformer != null;
final boolean needsPopulate = 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替换成这个改动后的源代码ViewPagerCompat,那么ViewPager切换动画的效果就出现了。
分析动画源代码,实现自己的动画效果
上面的动画源代码是我在Google的官方文档中找到的。里面完整的实现了一个系列动画的功能。那么我们是不是能够也能通过分析一下Google文档中源代码的写法。找到规律后,我们自己动手实现一个自己的动画效果呢?先来看一下DepthPageTransformer.java这段源代码,这个类实现了一个接口ViewPager.PageTransformer,重写了当中的一个方法
public void transformPage(View view, float position) {
...
Log.i("TAG", "view = " + view + ",position = " + position);
...
}
如上所看到的,我先在这种方法中打印出方法中的參数view对象和position的值,然后我们来看一下LOG的输出:
/**
* ViewPager自己定义旋转动画
*
* @author Vincent
*
*/
public class RotateDownTransformer implements PageTransformer { // 旋转的最大角度为20度
private static final float MAX_ROTATE = 20.0f;
// 旋转过程中的角度
private float currentRotate; @Override
public void transformPage(View view, float position) {
int pageWidth = view.getWidth();
Log.i("TAG", "view = " + view + ",position = " + position);
if (position < -1) {
ViewHelper.setRotation(view, 0);
} else if (position <= 0) {
// position范围[-1.0,0.0],此时A页动画移出屏幕
currentRotate = position * MAX_ROTATE;
// 设置当前页的旋转中心点,横坐标是屏幕宽度的1/2,纵坐标为屏幕的高度
ViewHelper.setPivotX(view, pageWidth / 2);
ViewHelper.setPivotY(view, view.getHeight());
ViewHelper.setRotation(view, currentRotate);
} else if (position <= 1) {
// position范围(0.0,1.0],此时B页动画移到屏幕
currentRotate = position * MAX_ROTATE;
// 设置当前页的旋转中心点,横坐标是屏幕宽度的1/2,纵坐标为屏幕的高度
ViewHelper.setPivotX(view, pageWidth / 2);
ViewHelper.setPivotY(view, view.getHeight());
ViewHelper.setRotation(view, currentRotate);
} else {
ViewHelper.setRotation(view, 0);
}
}
}
感谢CSDN博客专家鸿洋无私奉献的教程,教程视频地址:http://www.imooc.com/learn/226
版权声明:本文博客原创文章,博客,未经同意,不得转载。
Android至ViewPager添加切换动画——使用属性动画的更多相关文章
- Android为ViewPager添加切换动画——自己定义ViewPager
转载请注明出处:http://blog.csdn.net/allen315410/article/details/44224517 在上篇博客中,我写了一个使用属性动画为ViewPager加入切换动画 ...
- Android开发——View动画、帧动画和属性动画详解
0. 前言 Android动画是面试的时候经常被问到的话题.我们都知道Android动画分为三类:View动画.帧动画和属性动画. 先对这三种动画做一个概述: View动画是一种渐进式动画,通过图 ...
- Android动画基础——属性动画(Property Animation)
本篇涉及例子下载:Github 本篇讲android 3.0引入的属性动画框架,上篇写视图动画View Animation时就说过ViewAnimation的缺点,那就是动画作用的是view本身的视觉 ...
- android 学习随笔二十六(动画:属性动画)
属性动画,属性动画是真正改变对象的某个属性的值 * 补间动画,只是一个动画效果,组件其实还在原来的位置上,xy没有改变1.位移:* 第一个参数target指定要显示动画的组件* 第二个参数proper ...
- Android开发实战之补间动画和属性动画
说起动画,其实一点也不陌生,在使用一款app的时候为了优化用户体验,多多少少的,都会加入动画. 安卓中的动画,分为两大类:补间动画和属性动画.本篇博文会详细介绍总结这两大动画,希望本篇博文对你的学习和 ...
- View动画和属性动画
在应用中, 动画效果提升用户体验, 主要分为View动画和属性动画. View动画变换场景图片效果, 效果包括平移(translate), 缩放(scale), 旋转(rotate), 透明(alph ...
- Android为ViewPager增加切换动画——使用属性动画.
ViewPager作为Android最常用的的组件之一,相信大家在项目中会频繁的使用到的,例如利用ViewPager制作引导页.轮播图,甚至做整个app的表现层的框架等等. Android3.0以下不 ...
- Android 动画及属性动画
Android 平台提供了一套完整的动画框架,在Android3.0之前有两种动画Tween Animation(补间动画)和Frame Animation(帧动画), 对应SDK中的View Ani ...
- Android动画:模拟开关按钮点击打开动画(属性动画之平移动画)
在Android里面,一些炫酷的动画确实是很吸引人的地方,让然看了就赏心悦目,一个好看的动画可能会提高用户对软件的使用率.另外说到动画,在Android里面支持3种动画: 逐帧动画(Frame Ani ...
随机推荐
- 利用ArrayList对Hashtable其进行排序
前言: 最近在使用Hashtable的时候发现一个问题:就是当你对Hashtable进行遍历的时候整个输出结果是毫无顺序的, 上网查了一下说是Hashtable有自己内部的排序机制,如果要自定义排序的 ...
- Python WxPython 的安装以及使用
WxPython 网址 学习网址 http://wiki.wxpython.org/How%20to%20Learn%20wxPython 安装网址 http://wiki.wxpython.org/ ...
- C#判断文件是否正在被使用
生成文件的时候,如果该文件夹下的同名文件被打开(或者被使用),如果这时再生成一个同名文件,则会提示文件正在被占用. 解决方法有两个,一个是保存的文件名改成该文件夹下不存在的(随机数之类的XXOO都行, ...
- 阻塞队列BlockingQueue用法(转)
多线程环境中,通过队列可以很容易实现数据共享,比如经典的“生产者”和“消费者”模型中,通过队列可以很便利地实现两者之间的数据共享. 假设我们有若干生产者线程,另外又有若干个消费者线程.如果生产者线程需 ...
- 使用malloc分别分配2KB,6KB的内存空间,打印指针地址
#include<stdio.h> #include<stdlib.h> #include<string.h> #include<malloc.h> i ...
- flex中在basewidget中不能使用图表组件问题
参考 http://blog.sina.com.cn/s/blog_51e3d0e70101hljz.html
- 数独问题的介绍及POJ 2676-Sudoku(dfs+剪枝)
知道是数独问题后犹豫了一下要不要做(好像很难的样纸==.),用dfs并剪枝,是一道挺规范的搜索题. 先介绍以下数独吧- 数独(Sudoku)是一种运用纸.笔进行演算的逻辑游戏.玩家需要根据9×9盘面上 ...
- ExtJs4 笔记(1) ExtJs大比拼JQuery:Dom文档操作
现在主流的JS框架要数ExtJs和JQuery应用的比较广泛.JQuery属于轻量级的,一般做网站应用比较常见,可见块头小的优势.ExtJs比较庞大,它除了对基本的JS语法和HTML DOM操作方式的 ...
- javascript --- 事件托付
javascript 之 事件托付 长处:1.提高性能(仅仅须要对父级进行操作,子节点相同会拥有其相关属性和方法) 2.对于新加入的事件.也让其拥有父级事件的属性 <!doctype html& ...
- ie浏览器提交参数和其它浏览器的区别
场景描述: 用户注册模块(ajax提交方式,post方法),在url后追加了一个参数,如:url+‘btnvalue=中文参数’,如此在非ie浏览器注册时,功能完好,但在ie下注册不成功.调式后发现在 ...