微信号:jszj2014215

介绍:主要分享移动互联网的相关产品和资讯,关注你将学习到更多,在互联网的当下你会赚更多的钱...

Android动画的理解

2016-11-16 08:15 点这里

基础知识

Shape篇

使用Shape可以自定义形状,可以定义下面四种类型的形状,通过android:shape属性指定:

  • rectangle:矩形,默认的形状

  • oval:椭圆形,可以画正圆

  • line:线形,可以画实线和虚线

  • ring:环形,可以话进度条之类

rectange

  • solid : 设置形状填充的颜色,只有android:color一个属性

  • android:color  填充的颜色

  • padding : 设置内容与形状边界的内间距,可分别设置左右上下的距离


  • gradient : 设置形状的渐变颜色,可以是线性渐变、辐射渐变、扫描性渐变

  • android:type  渐变的类型 linear  线性渐变,默认的渐变类型 radial  放射渐变,设置该项时,android:gradientRadius也必须设置 sweep  扫描性渐变

  • android:useLevel  如果为true,则可在LevelListDrawable中使用

  • corners : 设置圆角,只适用于rectangle类型,可分别设置四个角不同半径的圆角,当设置的圆角半径很大时,比如200dp,就可变成弧形边了

  • stroke : 设置描边,可描成实线或虚线。

  • android:color  描边的颜色

  • android:width  描边的宽度

  • android:dashWidth  设置虚线时的横线长度

  • android:dashGap  设置虚线时的横线之间的距离

oval

它也有solid、padding、stroke、gradient、size几个特性,size是用来设置形状大小的,如下:

size: 设置形状默认的大小,可设置宽度和高度

android:width 宽度

android:height 高度

line

画线时,有几点特性必须要知道的:

  1. 只能画水平线,画不了竖线;

  2. 线的高度是通过stroke的android:width属性设置的;

  3. size的android:height属性定义的是整个形状区域的高度;

  4. size的height必须大于stroke的width,否则,线无法显示;

  5. 线在整个形状区域中是居中显示的;

  6. 线左右两边会留有空白间距,线越粗,空白越大;

  7. 引用虚线的view需要添加属性android:layerType,值设为"software",否则显示不了虚线。

Selector篇

shape只能定义单一的形状,而实际应用中,很多地方比如按钮、Tab、ListItem等都是不同状态有不同的展示形状。举个例子,一个按钮的背景,默认时是一个形状,按下时是一个形状,不可操作时又是另一个形状。有时候,不同状态下改变的不只是背景、图片等,文字颜色也会相应改变。而要处理这些不同状态下展示什么的问题,就要用selector来实现了。

那么,看看都有哪些状态可以设置呢:

  • android:state_enabled : 设置触摸或点击事件是否可用状态,一般只在false时设置该属性,表示不可用状态

  • android:state_pressed : 设置是否按压状态,一般在true时设置该属性,表示已按压状态,默认为false

  • android:state_selected : 设置是否选中状态,true表示已选中,false表示未选中

  • android:state_checked : 设置是否勾选状态,主要用于CheckBox和RadioButton,true表示已被勾选,false表示未被勾选

  • android:state_checkable : 设置勾选是否可用状态,类似state_enabled,只是state_enabled会影响触摸或点击事件,而state_checkable影响勾选事件

  • android:state_focused : 设置是否获得焦点状态,true表示获得焦点,默认为false,表示未获得焦点

  • android:state_window_focused : 设置当前窗口是否获得焦点状态,true表示获得焦点,false表示未获得焦点,例如拉下通知栏或弹出对话框时,当前界面就会失去焦点;另外,ListView的ListItem获得焦点时也会触发true状态,可以理解为当前窗口就是ListItem本身

  • android:state_activated : 设置是否被激活状态,true表示被激活,false表示未激活,API Level 11及以上才支持,可通过代码调用控件的setActivated(boolean)方法设置是否激活该控件

  • android:state_hovered : 设置是否鼠标在上面滑动的状态,true表示鼠标在上面滑动,默认为false,API Level 14及以上才支持

Layer-List篇

使用layer-list可以将多个drawable按照顺序层叠在一起显示。

关于item的用法,也做下总结:

  1. 根节点不同时,可设置的属性是会不同的,比如selector下,可以设置一些状态属性,而在layer-list下,可以设置偏移量;

  2. 就算父节点同样是selector,放在drawable目录和放在color目录下可用的属性也会不同,比如drawable目录下可用的属性为android:drawable,在color目录下可用的属性为android:color;

  3. item的子节点可以为任何类型的drawable类标签,除了上面例子中的shape、color、layer-list,也可以是selector,还有其他没讲过的bitmap、clip、scale、inset、transition、rotate、animated-rotate、lever-list等等。

Drawable资源篇

nine-patch标签

使用nine-patch标签可以对点九图片做一些设置处理,不过可设置的属性并不多:

  • android:src 必填项,必须指定点九类型的图片

  • android:dither 设置是否抖动,图片与屏幕的像素配置不同时会用到,比如图片是ARGB 8888的,而屏幕是RGB565

  • android:tint 给图片着色,比如图片本来是黑色的,着色后可以变成白色

  • android:tintMode 着色模式,API Level 21(Android 5.0)才添加的属性

  • android:alpha 设置图片的透明度,取值范围为0.0~1.0之间,0.0为全透明,1.0为全不透明,API Level最低要求是11

  • android:autoMirrored 设置图片是否需要镜像反转,当布局方向是RTL,即从右到左布局时才有用,API Level 19(Android 4.4)才添加的属性

scale标签

使用scale标签可以对drawable进行缩放操作,和clip一样是通过设置level来控制缩放的比例。scale标签可以设置的属性如下:

  • android:drawable 指定drawable资源,如果不设置该属性,也可以定义drawable类型的子标签

  • android:scaleHeight 设置可缩放的高度,用百分比表示,格式为XX%,0%表示不做任何缩放,50%表示只能缩放一半

  • android:scaleWidth 设置可缩放的宽度,用百分比表示,格式为XX%,0%表示不做任何缩放,50%表示只能缩放一半

  • android:scaleGravity 设置drawable缩放后的位置,取值和bitmap标签的一样,就不一一列举说明了,不过默认值是left

  • android:useIntrinsicSizeAsMinimum 设置drawable原有尺寸作为最小尺寸,设为true时,缩放基本无效,API Level最低要求为11

rotate标签

使用rotate标签可以对一个drawable进行旋转操作,在 shape篇 讲环形时最后举了个进度条时就用到了rotate标签。另外,比如你有一张箭头向上的图片,但你还需要一个箭头向下的图片,这时就可以使用rotate将向上的箭头旋转变成一张箭头向下的drawable。

先看看rotate标签的一些属性吧:

  • android:drawable 指定drawable资源,如果不设置该属性,也可以定义drawable类型的子标签

  • android:fromDegrees 起始的角度度数

  • android:toDegrees 结束的角度度数,正数表示顺时针,负数表示逆时针

  • android:pivotX 旋转中心的X坐标,浮点数或是百分比。浮点数表示相对于drawable的左边缘距离

Drawable Animation

其实说明动画的Drawable的资源按照一定顺序执行,最终出来的效果类似电影中一帧一帧的,它允许你实现像播放幻灯片一样的效果。

是它的根元素,做为根节点,

这里定义了三个drawable资源文件,每次执行时间为200ms,顺序是从上到下,这种动画最常见应用场景是在想表达电池充电的过程,从0%,25%,50%,100%表达连续充电的过程,就可以做四个不同的资源图片,然后按照一定的顺序,进而执行相应的运行时间。

有了动画文件之后,具体怎么用呢,如下:

AnimationDrawable rocketAnimation; 
public void onCreate(Bundle savedInstanceState) {  super.onCreate(savedInstanceState);
  setContentView(R.layout.main);
 
  ImageView rocketImage = (ImageView) findViewById(R.id.rocket_image);
  rocketImage.setBackgroundResource(R.drawable.rocket_thrust);
  rocketAnimation = (AnimationDrawable) rocketImage.getBackground();
} 
 
public boolean onTouchEvent(MotionEvent event) {  if (event.getAction() == MotionEvent.ACTION_DOWN) {
    rocketAnimation.start();    return true; 
  } 
  return super.onTouchEvent(event);
}

特别注意,AnimationDrawable的start()方法不能在Activity的onCreate方法中调运,因为AnimationDrawable还未完全附着到window上,所以最好的调运时机是onWindowFocusChanged()方法中。

其中Drawable Animation还有一个 animated-rotate 属性来定义旋转动画,这个用法也是类似的,不再过多讲述。

View Animation

引用官方文档

视图动画,也叫Tween(补间)动画可以在一个视图容器内执行一系列简单变换(位置、大小、旋转、透明度)。譬如,如果你有一个TextView对象,您可以移动、旋转、缩放、透明度设置其文本,当然,如果它有一个背景图像,背景图像会随着文本变化。

补间动画通过XML或Android代码定义,建议使用XML文件定义,因为它更具可读性、可重用性。

Animation控制的是整个View,实现的原理是每次绘制视图时,View所在的ViewGroup的drawChild函数获取该View的Animation的Transformation值,然后调用canvas.concat(transformToApply.getMatrix()),通过矩阵运算完成动画帧。如果动画没完成,就继续调用invalidate()函数,启动下次绘制来驱动动画,从而完成整个动画的绘制。

视图动画使用简单,主要有以下四种类型动画:

  • Alpha Animation

  • Rotate Animation

  • Translate Animation

  • Scale Animation

并提供了AnimationSet动画集合,混合使用多种动画方式,在Android 3.0之前,View Animation一家独大,但是随着Property Animation的推出,风光就大不如前,相比属性动画,视图动画一个最大的缺陷是不具备交互性,当某个元素发生视图动画后,其响应的事件的位置还依然在动画前的地方,所以视图动画只能做普通的动画效果,避免交互的发生,但它的优点是,效率高而且使用方便。

Alpha Animation

可以实现透明度渐变的动画效果,也就是淡入淡出的效果,可通过设置下面三个属性来设置淡入或淡出效果:

  • android:duration  动画从开始到结束持续的时长,单位为毫秒

  • android:fromAlpha  动画开始时的透明度,0.0为全透明,1.0为不透明,默认为1.0

  • android:toAlpha  动画结束时的透明度,0.0为全透明,1.0为不透明,默认为1.0

当设置开始时透明度为0.0,结束时为1.0,就能实现淡入效果;相反,当设置开始时透明度为1.0,结束时为0.0,那就能实现淡出效果。示例代码如下:

<!-- res/anim/fade_in.xml -->
<?xml version="1.0" encoding="utf-8"?>
<alpha xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="1000"
    android:fromAlpha="0.0"
    android:toAlpha="1.0" />

将这动画效果添加到View上也只需要一行代码:

view.startAnimation(AnimationUtils.loadAnimation(this, R.anim.fade_in));

将这动画效果添加到View上也只需要一行代码:

Rotate Animation

可以实现旋转的动画效果,主要的属性如下:

  • android:duration  动画从开始到结束持续的时长,单位为毫秒

  • android:fromDegrees  旋转开始的角度

  • android:toDegrees  旋转结束的角度

  • android:pivotX  旋转中心点的X坐标,纯数字表示相对于View本身左边缘的像素偏移量;带"%"后缀时表示相对于View本身左边缘的百分比偏移量;带"%p"后缀时表示相对于父View左边缘的百分比偏移量

  • android:pivotY  旋转中心点的Y坐标,纯数字表示相对于View本身顶部边缘的像素偏移量;带"%"后缀时表示相对于View本身顶部边缘的百分比偏移量;带"%p"后缀时表示相对于父View顶部边缘的百分比偏移量

以下示例代码旋转角度从0到360,即旋转了一圈,旋转的中心点都设为了50%,即是View本身中点的位置。

<!-- res/anim/rotate_one.xml -->
<?xml version="1.0" encoding="utf-8"?>
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="2000"
    android:fromDegrees="0"
    android:toDegrees="360"
    android:pivotX="50%"
    android:pivotY="50%" />

标签对应的类为RotateAnimation,父类也是Animation,添加到View上的代码如下:

RotateAnimation rotateAnimation = (RotateAnimation) AnimationUtils.loadAnimation(this, R.anim.rotate_one);
view.startAnimation(rotateAnimation);

Translate Animation

可以实现位置移动的动画效果,可以是垂直方向的移动,也可以是水平方向的移动。坐标的值可以有三种格式:从-100到100,以"%"结束,表示相对于View本身的百分比位置;如果以"%p"结束,表示相对于View的父View的百分比位置;如果没有任何后缀,表示相对于View本身具体的像素值。主要的属性如下:

  • android:duration  动画从开始到结束持续的时长,单位为毫秒

  • android:fromXDelta  起始位置的X坐标的偏移量

  • android:toXDelta  结束位置的X坐标的偏移量

  • android:fromYDelta  起始位置的Y坐标的偏移量

  • android:toYDelta  结束位置的Y坐标的偏移量

看示例吧,以下代码实现的是从左到右的移动效果,起始位置为相对于控件本身-100%的位置,即在控件左边,与控件本身宽度一致的位置;结束位置为相对于父控件100%的位置,即会移出父控件右边缘的位置。

<!-- res/anim/move_left_to_right.xml -->
<?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="2000"
    android:fromXDelta="-100%"
    android:fromYDelta="0"
    android:toXDelta="100%p"
    android:toYDelta="0" />

标签对应的类为TranslateAnimation,父类也是Animation,添加到View上的代码如下:

TranslateAnimation moveAnimation = (TranslateAnimation) AnimationUtils.loadAnimation(this, R.anim.move_left_to_right);
view.startAnimation(moveAnimation);

Scale Animation

可以实现缩放的动画效果,主要的属性如下:

  • android:duration  动画从开始到结束持续的时长,单位为毫秒

  • android:fromXScale  动画开始时X坐标上的缩放尺寸

  • android:toXScale  动画结束时X坐标上的缩放尺寸

  • android:fromYScale  动画开始时Y坐标上的缩放尺寸

  • android:toYScale  动画结束时Y坐标上的缩放尺寸
    PS : 以上四个属性,0.0表示缩放到没有,1.0表示正常无缩放,小于1.0表示收缩,大于1.0表示放大

  • android:pivotX  缩放时的固定不变的X坐标,一般用百分比表示,0%表示左边缘,100%表示右边缘

  • android:pivotY  缩放时的固定不变的Y坐标,一般用百分比表示,0%表示顶部边缘,100%表示底部边缘

具体示例:

<!-- res/anim/zoom_out.xml -->
<?xml version="1.0" encoding="utf-8"?>
<scale xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="1000"
    android:fromXScale="1.0"
    android:fromYScale="1.0"
    android:pivotX="0%"
    android:pivotY="100%"
    android:toXScale="1.5"
    android:toYScale="1.5" />

对应的类为ScaleAnimation,父类也是Animation,添加到View上的用法和AlphaAnimation一样,代码如下:

ScaleAnimation zoomOutAnimation = (ScaleAnimation) AnimationUtils.loadAnimation(this, R.anim.zoom_out);
view.startAnimation(zoomOutAnimation);

Set Animation

标签可以将多个动画组合起来,变成一个动画集。比如想将一张图片缩放的同时也做移动,这时候就要用set标签组合缩放动画和移动动画了。示例代码如下:

<!-- res/anim/move_and_scale.xml -->
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="2000">
    <translate
        android:fromXDelta="0"
        android:fromYDelta="0"
        android:toXDelta="200%"
        android:toYDelta="0" />
    <scale
        android:fromXScale="1.0"
        android:fromYScale="1.0"
        android:pivotX="0%"
        android:pivotY="100%"
        android:toXScale="1.5"
        android:toYScale="1.5" />
</set>

以上代码实现的动画效果为向右移动的同时也同步放大。Set标签在视图动画中除了可以组合Alpha ,Rotate , Scale , Scale 这四种标签,也可以嵌套其他Set标签。

Property Animat

视图动画只能作用于View,而且视图动画改变的只是View的绘制效果,View真正的属性并没有改变。比如,一个按钮做平移的动画,虽然按钮的确做了平移,但按钮可点击的区域并没随着平移而改变,还是在原来的位置。而属性动画则可以改变真正的属性,从而实现按钮平移时点击区域也跟着平移。通俗点说,属性动画其实就是在一定时间内,按照一定规律来改变对象的属性,从而使对象展现出动画效果。

属性动画是在android 3.0引入的动画体系,如果还想适配基本已经灭绝的2.x版本,只好绕道了。

属性动画和视图动画一样,可以通过xml文件定义,不同的是,视图动画的xml文件放于 res/anim/目录下,而属性动画的xml文件则放于 res/animator/ 目录下。一个是 anim ,一个是 animator,别搞错了。同样的,在Java代码里引用属性动画的xml文件时,则用 R.animator.filename ,不同于视图动画,引用时为 R.anim.filename 。

属性动画主要有三个元素: animator , objectAnimator , set

相对应的有三个类: ValueAnimator 、 ObjectAnimator 、 AnimatorSet 。

ValueAnimator是基本的动画类,处理值动画,通过监听某一值的变化,进行相应的操作。ObjectAnimator 是 ValueAnimator 的子类,处理对象动画。 AnimatorSet 则为动画集,可以组合另外两种动画或动画集。相应的三个标签元素的关系也一样。

样式开发主要还是用xml的形式,所以这里先主要还是讲标签的用法。

animator

animator标签与对应的 ValueAnimator 类提供了属性动画的核心功能,包括计算动画值、动画时间细节、是否重复等。执行属性动画分两个步骤:

  1. 计算动画值

  2. 将动画值应用到对象和属性上

ValuAnimiator只完成第一步,即只计算值,要实现第二步则需要在值变化的监听器里自行更新对象属性。

通过animator标签可以很方便的对 ValuAnimiator 进行设置,可设置的属性如下:

  • android:duration  动画从开始到结束持续的时长,单位为毫秒

  • android:startOffset  设置动画执行之前的等待时长,单位为毫秒

  • android:repeatCount  设置动画重复执行的次数,默认为0,即不重复;可设为-1或infinite,表示无限重复

  • android:repeatMode  设置动画重复执行的模式,可设为以下两个值其中之一:

  • restart  动画重复执行时从起点开始,默认为该值

  • reverse  动画会反方向执行

  • android:valueFrom  动画开始的值,可以为int值、float值或color值

  • android:valueTo  动画结束的值,可以为int值、float值或color值

  • android:valueType  动画值类型,若为color值,则无需设置该属性

  • intType  指定动画值,即以上两个value属性的值为整型

  • floatType  指定动画值,即以上两个value属性的值为浮点型,默认值

  • android:interpolator  设置动画速率的变化,比如加速、减速、匀速等,需要指定Interpolator资源。

接着,用一个实例讲解具体的用法吧。在这个例子里,将一个按钮的宽度进行缩放,从100%缩放到20%。

xml文件的代码如下:

<!-- res/animator/value_animator.xml -->
<?xml version="1.0" encoding="utf-8"?>
<animator xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="3000"
    android:valueFrom="100"
    android:valueTo="20"
    android:valueType="intType" />

可看到,值的变化从100到20,动画时长3000毫秒,

按钮默认是填充屏幕宽度的,点击时的执行方法为onScaleWidth,以下则是onScaleWidth方法的代码:

public void onScaleWidth(final View view) {    // 获取屏幕宽度
    final int maxWidth = getWindowManager().getDefaultDisplay().getWidth();
    ValueAnimator valueAnimator = (ValueAnimator) AnimatorInflater.loadAnimator(this, R.animator.value_animator);
    valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {        @Override
        public void onAnimationUpdate(ValueAnimator animator) {            // 当前动画值,即为当前宽度比例值
            int currentValue = (Integer) animator.getAnimatedValue();            // 根据比例更改目标view的宽度
            view.getLayoutParams().width = maxWidth * currentValue / 100;
            view.requestLayout();
        }
    });
    valueAnimator.start();
}

从中,我们可以看到属性动画则是通过 AnimatorInflater 类的 loadAnimation() 方法获取相应的 Animator 类实例。另外, ValueAnimator 通过添加AnimatorUpdateListener监听器监听值的变化,从而再手动更新目标对象的属性。最后,通过调用 valueAnimator.start() 方法启动动画。

objectAnimator

objectAnimator标签对应的类为ObjectAnimator,为 ValueAnimator 的子类。objectAnimator标签与标签animator不同的是,可以直接指定动画的目标对象的属性。标签可设置的属性除了和一样的那些,另外多了一个:

  • android:propertyName  目标对象的属性名,要求目标对象必须提供该属性的setter方法,如果动画的时候没有初始值,还需要提供getter方法

还是用实例说明具体用法,还是用上面的例子,将一个按钮的宽度进行缩放,从100%缩放到20%,但这次改用objectAnimator实现。

个 android:propertyName 的属性,设置值为width。也就是说,动画改变的属性为width,值将从100逐渐减到20。另外,值是从setWidth()传递过去的,再从getWidth()获取。而且,这里设置的值代表的是比例值,因此,还需要进行计算转化为实际的宽度值。最后,对象实际的宽度值为 view.getLayoutParams().width 。因此,需要用一个包装类来包装原始的view对象,对其提供setWidth()和getWidth()方法,代码如下:
private static class ViewWrapper {    private View target; //目标对象
    private int maxWidth; //最长宽度值

    public ViewWrapper(View target, int maxWidth) {        this.target = target;        this.maxWidth = maxWidth;
    }    public int getWidth() {        return target.getLayoutParams().width;
    }    public void setWidth(int widthValue) {        //widthValue的值从100到20变化
        target.getLayoutParams().width = maxWidth * widthValue / 100;
        target.requestLayout();
    }
}

上面setWidth()的代码里,根据比例值转化为了实际的宽度值。最后,动画处理的代码如下:

public void onScaleWidth(View view) {    // 获取屏幕宽度
    int maxWidth = getWindowManager().getDefaultDisplay().getWidth();    // 将目标view进行包装
    ViewWrapper wrapper = new ViewWrapper(view, maxWidth);    // 将xml转化为ObjectAnimator对象
    ObjectAnimator objectAnimator = (ObjectAnimator) AnimatorInflater.loadAnimator(this, R.animator.object_animator);    // 设置动画的目标对象为包装后的view
    objectAnimator.setTarget(wrapper);    // 启动动画
    objectAnimator.start();
}

ObjectAnimator提供了属性的设置,但相应的需要有该属性的setter和getter方法。而ValueAnimator 则只是定义了值的变化,并不指定目标属性,所以也不需要提供setter和getter方法,但只能在AnimatorUpdateListener监听器里手动更新属性。不过,也因为没有指定属性,所以其实更具灵活性了,你可以在监听器里根据值的变化做任何事情,比如更新多个属性,比如在缩放宽度的同时做垂直移动。

为了对View更方便的设置属性动画,Android系统也提供了View的一些属性和相应的setter和getter方法:

  • alpha :透明度,默认为1,表示不透明,0表示完全透明

  • pivotX  和  pivotY :旋转的轴点和缩放的基准点,默认是View的中心点

  • scaleX  和  scaleY :基于pivotX和pivotY的缩放,1表示无缩放,小于1表示收缩,大于1则放大

  • rotation 、 rotationX  和  rotationY :基于轴点(pivotX和pivotY)的旋转,rotation为平面的旋转,rotationX和rotationY为立体的旋转

  • translationX  和  translationY :View的屏幕位置坐标变化量,以layout容器的左上角为坐标原点

  • x  和  y :View在父容器内的最终位置,是左上角坐标和偏移量(translationX,translationY)的和

set

set标签对应于 AnimatorSet 类,可以将多个动画组合成一个动画集,如上面提到的在缩放宽度的同时做垂直移动,可以将一个缩放宽度的动画和一个垂直移动的动画组合在一起。

set标签有一个属性可以设置动画的时序关系:

  • android:ordering  设置动画的时序关系,取值可为以下两个值之一: together  动画同时执行,默认值 sequentially  动画按顺序执行

那如果想有些动画同时执行,有些按顺序执行,该怎么办呢?因为set标签是可以嵌套其他set标签的,也就是说可以将同时执行的组合在一个set标签,再嵌在按顺序执行的set标签内。

<!-- res/animator/animator_set.xml -->
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:ordering="together">
    <objectAnimator
        android:duration="3000"
        android:propertyName="width"
        android:valueFrom="100"
        android:valueTo="20"
        android:valueType="intType" />
    <objectAnimator
        android:duration="3000"
        android:propertyName="marginTop"
        android:valueFrom="0"
        android:valueTo="100"
        android:valueType="intType" />
</set>

以上代码可实现两个同时执行的动画,一个将width从100缩放到20,一个将marginTop从0增加到100。多了一个marginTop属性,那么,在ViewWrapper添加setMarginTop()方法,添加后的ViewWrapper类代码如下:

private static class ViewWrapper {    private View target;    private int maxWidth;    public ViewWrapper(View target, int maxWidth) {        this.target = target;        this.maxWidth = maxWidth;
    }    public int getWidth() {        return target.getLayoutParams().width;
    }    public void setWidth(int widthValue) {
        target.getLayoutParams().width = maxWidth * widthValue / 100;
        target.requestLayout();
    }    public void setMarginTop(int margin) {
        LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams) target.getLayoutParams();
        layoutParams.setMargins(0, margin, 0, 0);
        target.setLayoutParams(layoutParams);
    }
}

最后,动画处理的代码:

public void onScaleWidth(View view) {    // 获取屏幕宽度
    int maxWidth = getWindowManager().getDefaultDisplay().getWidth();    // 将目标view进行包装
    ViewWrapper wrapper = new ViewWrapper(view, maxWidth);    // 将xml转化为ObjectAnimator对象
    AnimatorSet animatorSet = (AnimatorSet) AnimatorInflater.loadAnimator(this, R.animator.animator_set);    // 设置动画的目标对象为包装后的view
    animatorSet.setTarget(wrapper);    // 启动动画
    animatorSet.start();
}

这样就实现了宽度缩放和垂直移动的效果。

当然,在Android3.0之后,Google给View增加了animate方法来直接驱动属性动画,代码如下:

view.animate().x(50f).y(100f);

小结

目前到此为止,我们了解到在Android中有三种不同的动画类型,在Android3.0版本其实是一个区分点,在3.0之前用的居多都是View Animation,而在3.0之后用的居多是Property Animation,本次介绍的是这三者之间的区别和不同用法。

 

来自:http://www.cnblogs.com/cr330326/p/6062032.html


 
Android技术之家 更多文章 减少APK的大小,Android官方这样说 热修复框架HotFix源码解析 巧用Android图片资源,打造更精致的APP 让你的studio 的Gradle编译上高速 一个2年安卓开发者的一些忠告
猜您喜欢 不懂点CAP理论,你好意思说你是做分布式的吗? PostgreSQL与Linux内核版本 iOS完全自学手册——[三]Objective-C语言速成,利用Objective-C创建自己的对象 【722】警务大数据分析模型构想,基于物联网技术的干活 一场刷爆朋友圈的发布会和一个彩蛋