Android 动画

来源:互联网 发布:乐清市知临中学 编辑:程序博客网 时间:2024/06/14 13:53

Android动画

  • Android动画
    • 前言
    • 动画分类
    • 如何加载动画
      • 渐变动画
      • 帧动画
      • 属性动画


前言

之前一直没有系统地学习Android中的动画,每当编码需要动画效果的时候,总是很郁闷。虽然网上已经有很多相关的教程,但是自己还是做个总结:简单简洁!


动画分类

简单地说,动画就几种类型:渐变、平移、旋转等,Android中:

  • Tween Animation 渐变动画
    包含了渐变alpha、平移translate,旋转rotate,伸缩scale,这四个还是比较常见、基础的动画

  • Frame Animation 帧动画
    事先把所有的动画画面准备好,一帧一帧地放,相当于放电影

  • Property Animation 属性动画
    对View的属性进行变化,达到动画效果


如何加载动画

简单记住上面三种动画的属性就可以了,重要的是:如何加载动画。

渐变动画

对于渐变动画,如何将一个View(例如ImageView)实现渐变(或者缩放等)? 加载动画代码如下:

  • 先定义动画文件 /res/drawable/anim/alpha.xml
<?xml version="1.0" encoding="utf-8"?><set xmlns:android="http://schemas.android.com/apk/res/android">    <alpha        android:duration="2000"        android:fromAlpha="1.0"        android:interpolator="@android:anim/linear_interpolator"        android:toAlpha="0" /></set>

其中 duration 表示整个动画的时间,而对于一个渐变动作来说,会有一个起始透明值 fromAlpha 和结束透明值 toAlphainterpolator 是一个插补器,简单理解就是指定的动作效果,如实现加速、减速变化等

  • 对某个View加载动画
private ImageView photo;...Animation alpha = AnimationUtils.loadAnimation(MainActivity.this, R.anim.alpha); // 加载animphoto.startAnimation(alpha); // 执行动画

以上是通过加载xml文件加载动画的,如果通过java来加载动画,则:

AlphaAnimation alpha = new AlphaAnimation(1.0f, 0);alpha.setDuration(2000);photo.startAnimation(alpha);

当然,有时候想同时两个动画一起加载,例如平移和渐变一起,通过 AnimationSet 类添加多个Animation实现:

// 渐变动画Animation alpha = AnimationUtils.loadAnimation(MainActivity.this, R.anim.alpha);alpha.setDuration(2000);// 平移动画TranslateAnimation translate = new TranslateAnimation(0, 160, 0, 160);translate.setDuration(2000);// 添加多个Animation实现同时加载多个动画AnimationSet set = new AnimationSet(false);set.addAnimation(alpha);set.addAnimation(translate);set.setFillAfter(true);// 执行动画photo.startAnimation(set);

对于渐变动画的属性,不同动画有不同的属性,这里列举,只需要大概记住,以后需要查找:

  • translate :位移肯定涉及到了坐标、位置
属性名 意义 fromXDelta X轴方向开始位置,可以是数值、%、%p(p表示相对于父布局) toXDelta X轴方向结束位置,可以是数值、%、%p(p表示相对于父布局) fromYDelta Y轴方向开始位置,可以是数值、%、%p(p表示相对于父布局) toYDelta Y轴方向结束位置,可以是数值、%、%p(p表示相对于父布局)
  • scale:伸缩则涉及到了缩放比例
属性名 意义 fromXScale 起始的X方向上相对自身的缩放比例,浮点数,1.0表示本身 toXDelta 结束时的X方向上相对自身的缩放比例,浮点数,1.0表示本身 fromYDelta 起始的Y方向上相对自身的缩放比例,浮点数,1.0表示本身 toYDelta 结束时的X方向上相对自身的缩放比例,浮点数,1.0表示本身 pivotX 缩放时起点的X轴坐标,可以是数值、%、%p pivotY 缩放时起点的Y轴坐标,可以是数值、%、%p
  • alpha:渐变会涉及到显示的透明度
属性名 意义 fromAlpha 动画开始时的透明度,浮点数,1.0表示不透明 toAlpha 动画结束时的透明度,浮点数,1.0表示不透明
  • rotate:旋转会涉及到旋转的角度
属性名 意义 fromDegrees 动画开始时旋转的角度位置,正代表顺时针度数 toDegrees 动画结束时旋转的角度位置,正代表顺时针度数 pivotX 旋转开始时的X轴坐标,可以是数值、%、%p pivotY 旋转开始时的Y轴坐标,可以是数值、%、%p
  • 通用属性(也就是以上四者均有)
属性名 意义 duration 动画持续时间,以毫秒为单位 fillAfter 是否在动画结束时保持动画最后时的状态 fillBefore 是否在动画结束时还原动画最初时的状态 repeatCount 重复次数 repeatMode 有reverse和restart两个值,reverse表示倒序回放,restart表示重新放一遍 interpolator 指定的动作效果,例如动作速度、弹跳等
  • interpolator 属性
属性名 意义 linear_interpolator 以常量速率改变 decelerate_interpolator 动画由快变慢 cycle_interpolator 动画循环播放特定的次数,速率改变沿着正弦曲线 bounce_interpolator 动画结束时弹起 overshoot_interpolator 向前甩一定值后再回到原来位置

总结: 以上就是渐变动画的加载,相对还是比较简单,通过编写xml文件,然后通过 AnimationUtils 加载动画,或者new一个Animation的类对象(如TranslateAnimation),最后通过 startAnimation() 方法执行动画。

帧动画

帧动画需要实现提供对应动画“每一帧”的画面,执行动画的时候,将每一个动画播放出来。
如何加载帧动画?——通过 AnimationDrawable 加载,需要实现在drawables编写对应的xml文件: /res/drawable/frame.xml

<?xml version="1.0" encoding="utf-8"?><animation-list xmlns:android="http://schemas.android.com/apk/res/android"    android:oneshot="false">    <item android:drawable="@drawable/btn_star_off_disabled_holo_dark" android:duration="500" />    <item android:drawable="@drawable/btn_star_off_disabled_holo_light" android:duration="500" />    <item android:drawable="@drawable/btn_star_off_focused_holo_dark" android:duration="500" />    <item android:drawable="@drawable/btn_star_off_focused_holo_light" android:duration="500" /></animation-list>

其中, oneshot 为true表示动画是只播放一次,并停在最后一帧,false则动画循环播放;该动画共4帧,每一帧持续500ms。
接下来通过 AnimationDrawable 来执行动画:

AnimationDrawable frame = (AnimationDrawable) getResources().getDrawable(R.drawable.frame);photo.setBackgroundDrawable(anim);frame.start();

属性动画

我觉得后面这文章的属性动画讲得很好:Android属性动画深入分析:让你成为动画牛人

属性动画主要针对属性进行变换从而实现动画效果,例如将ImageView的宽度增加(针对View的width)、位置的改变(针对View 的translateX)、透明度改变等,先大概说如何加载属性动画。

  • 确定对View的某个属性进行变换,例如偏移量translationX:
// 获取mView的translationX属性,将translationX属性从0变换到500ObjectAnimator transAnim = ObjectAnimator.ofFloat(mView, "translationX", 0, 500);transAnim.setDuration(200);transAnim.start(); //执行动画
  • 原理
    属性动画要求动画作用的对象提供该属性的get和set方法,属性动画根据你传递的初始值和最终值,以动画的效果多次去调用set方法,每次传递给set方法的值都不一样,确切来说是随着时间的推移,所传递的值越来越接近最终值。当你对view的属性xxx做动画,如果想让动画生效,要同时满足两个条件:

    1. view必须要提供setXxx方法,如果动画的时候没有传递初始值,那么还要提供getXxx方法,因为系统要去拿xxx属性的初始值(如果这条不满足,程序直接Crash)
    2. object的setXxx对属性xxx所做的改变必须能够通过某种方法反映出来,比如会带来ui的改变(如果这条不满足,动画无效果但不会Crash)
  • 对任何属性执行动画
    Android中有一些view的属性并没有提供getter或setter,或者setter或getter并非直接操作view的对应属性,例如TextView的setWidth()和getWidth()并非直接操作width和height,所以需要通过获取其LayoutParams来改变其width和height属性。

    参照上文链接的文章,实现一个 ViewWrapper 类来封装我们的View的各个属性,从而能够通过属性动画来加载动画:

public static class ViewWrapper {    private View targetView;    public ViewWrapper(View targetView) {        this.targetView = targetView;    }    public int getWidth() {        return targetView.getLayoutParams().width;    }    public void setWidth(int width) {        targetView.getLayoutParams().width = width;        targetView.requestLayout();    }    public int getHeight() {        return targetView.getLayoutParams().height;    }    public void setHeight(int height) {        targetView.getLayoutParams().height = height;        targetView.requestLayout();    }    public float getTranslationX() {        return targetView.getTranslationX();    }    public void setTranslationX(float translationX) {        targetView.setTranslationX(translationX);    }    public float getTranslationY() {        return targetView.getTranslationY();    }    public void setTranslationY(float translationY) {        targetView.setTranslationY(translationY);    }}
0 0
原创粉丝点击