android动画使用介绍(属性动画)

1、属性动画介绍

属性动画是Android提供用于改变对象属性值,从而达到动画效果,可以完成复杂的动画效果

2、动画属性提供的Api以及方法

ValueAnimator 属性动画重要的一个类,常用的方法:

方法 介绍
ValueAnimator.ofInt(int… values) 可变参数,从初始值到结束值的变化,比如从(1,10,5) 从1到10哉变化到5
ValueAnimator.ofFloat(float… values) 同上,就是参数的基本类型不一样
ValueAnimator.ofObject(TypeEvaluator evaluator, Object… values) evaluator 估值器,就是决定从初始值到结束值变化的逻辑, values,同上
ValueAnimator.ofArgb(int… values) 同ofInt意思一样

3、 ValueAnimator.ofInt(int… values) 使用

传入三个参数(1,3,1)就是开始值是1中间变化到3之后最终为1

 ValueAnimator valueAnimator=ValueAnimator.ofInt(1,3,1);
        //设置动画时长
        valueAnimator.setDuration(200);
        //设置插值器 ,动画执行的速率,比如匀速,或者是先加速后减速
        valueAnimator.setInterpolator(new LinearInterpolator());
        //动画重复的次数
        valueAnimator.setRepeatCount(1);
        //动画重复的模式
        valueAnimator.setRepeatMode(ValueAnimator.RESTART);
        //设置动画执行监听,用来改变对象属性
        valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                Log.e("TAG","============="+animation.getAnimatedValue());
            }
        });
        valueAnimator.start();

可以看到开始值是1,结束值也是1

08-17 22:03:37.705 1715-1715/camera.test.com.animation E/TAG: =============1
08-17 22:03:37.705 1715-1715/camera.test.com.animation E/TAG: =============1
08-17 22:03:37.875 1715-1715/camera.test.com.animation E/TAG: =============2
08-17 22:03:37.925 1715-1715/camera.test.com.animation E/TAG: =============1
08-17 22:03:37.965 1715-1715/camera.test.com.animation E/TAG: =============2
08-17 22:03:37.975 1715-1715/camera.test.com.animation E/TAG: =============2
08-17 22:03:37.995 1715-1715/camera.test.com.animation E/TAG: =============2
08-17 22:03:38.015 1715-1715/camera.test.com.animation E/TAG: =============3
08-17 22:03:38.025 1715-1715/camera.test.com.animation E/TAG: =============3
08-17 22:03:38.045 1715-1715/camera.test.com.animation E/TAG: =============3
08-17 22:03:38.065 1715-1715/camera.test.com.animation E/TAG: =============2
08-17 22:03:38.075 1715-1715/camera.test.com.animation E/TAG: =============2
08-17 22:03:38.095 1715-1715/camera.test.com.animation E/TAG: =============2
08-17 22:03:38.115 1715-1715/camera.test.com.animation E/TAG: =============1

4、 ValueAnimator.ofFloat(float… values) 使用

ValueAnimator valueAnimator=  ValueAnimator.ofFloat(1,3);
        //设置动画时长
        valueAnimator.setDuration(200);
        //设置插值器 ,动画执行的速率,比如匀速,或者是先加速后减速
        valueAnimator.setInterpolator(new LinearInterpolator());
        //动画重复的次数
        valueAnimator.setRepeatCount(1);
        //动画重复的模式
        valueAnimator.setRepeatMode(ValueAnimator.RESTART);
        //设置动画执行监听,用来改变对象属性
        valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                Log.e("TAG","============="+animation.getAnimatedValue());
            }
        });
        valueAnimator.start();

开1.0到3.0

08-17 22:05:14.435 1782-1782/? E/TAG: =============1.0
08-17 22:05:14.445 1782-1782/? E/TAG: =============1.0
08-17 22:05:14.875 1782-1782/? E/TAG: =============1.1700001
08-17 22:05:14.905 1782-1782/? E/TAG: =============3.0

5、 ValueAnimator.ofArgb(int… values) 使用

主要用于颜色的变化,api>=21的时候才能使用

 ValueAnimator valueAnimator=  ValueAnimator.ofArgb(Color.RED,Color.BLUE);
        //设置动画时长
        valueAnimator.setDuration(200);
        //设置插值器 ,动画执行的速率,比如匀速,或者是先加速后减速
        valueAnimator.setInterpolator(new LinearInterpolator());
        //动画重复的次数
        valueAnimator.setRepeatCount(1);
        //动画重复的模式
        valueAnimator.setRepeatMode(ValueAnimator.RESTART);
        //设置动画执行监听,用来改变对象属性
        valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                Log.e("TAG","============="+animation.getAnimatedValue());
            }
        });
        valueAnimator.start();

可以设置view的颜色变化

2019-08-17 22:11:34.995 5829-5829/camera.test.com.animation E/TAG: =============-65536
2019-08-17 22:11:35.020 5829-5829/camera.test.com.animation E/TAG: =============-65536
2019-08-17 22:11:35.125 5829-5829/camera.test.com.animation E/TAG: =============-4587334
2019-08-17 22:11:35.176 5829-5829/camera.test.com.animation E/TAG: =============-7864096
2019-08-17 22:11:35.183 5829-5829/camera.test.com.animation E/TAG: =============-9436949
2019-08-17 22:11:35.197 5829-5829/camera.test.com.animation E/TAG: =============-11337483
2019-08-17 22:11:35.213 5829-5829/camera.test.com.animation E/TAG: =============-16776961
2019-08-17 22:11:35.230 5829-5829/camera.test.com.animation E/TAG: =============-720813
2019-08-17 22:11:35.247 5829-5829/camera.test.com.animation E/TAG: =============-1376144
2019-08-17 22:11:35.263 5829-5829/camera.test.com.animation E/TAG: =============-2097016
2019-08-17 22:11:35.280 5829-5829/camera.test.com.animation E/TAG: =============-2883429
2019-08-17 22:11:35.297 5829-5829/camera.test.com.animation E/TAG: =============-3735380
2019-08-17 22:11:35.314 5829-5829/camera.test.com.animation E/TAG: =============-4587334
2019-08-17 22:11:35.330 5829-5829/camera.test.com.animation E/TAG: =============-5570360
2019-08-17 22:11:35.347 5829-5829/camera.test.com.animation E/TAG: =============-6684459
2019-08-17 22:11:35.364 5829-5829/camera.test.com.animation E/TAG: =============-7864096
2019-08-17 22:11:35.380 5829-5829/camera.test.com.animation E/TAG: =============-9436949
2019-08-17 22:11:35.397 5829-5829/camera.test.com.animation E/TAG: =============-11468554
2019-08-17 22:11:35.414 5829-5829/camera.test.com.animation E/TAG: =============-16776961

6、 ValueAnimator.ofObject(TypeEvaluator evaluator, Object… values) 使用

ofObject的使用稍微复杂一样,需要一个估值器,什么是估值器,我理解就是生成动画某个时间点,返回的属性值,为什么ofIntofArgbofFloat 没有设置这估值器呢,其实都又设置,只不过系统为我们提供好直接用了,那又为什么ofObject没有呢,因为ofIntofArgbofFloat要改变的值都是基本类型,ofObject` 要传入的值是自定义的引用类型,自定义引用类型中属性无法预知,所以需要自己定义。

6.1、创建Object的对象
class MyLayoutParam{
        private int width;
        private int height;
        public MyLayoutParam(int width, int height) {
            this.width = width;
            this.height = height;
        }

        public int getWidth() {
            return width;
        }

        public void setWidth(int width) {
            this.width = width;
        }

        public int getHeight() {
            return height;
        }
        
        public void setHeight(int height) {
            this.height = height;
        }
        
        @Override
        public String toString() {
            return "width:::"+width+"---------height::::::::::"+height;
        }
    }
6.2、创建自定义的TypeEvaluator 估值器

TypeEvaluator 是系统提供的一个接口,我们实现他并重写里边的方法即可

 class MyTypeEvaluator implements TypeEvaluator{
        @Override
        public Object evaluate(float fraction, Object startValue, Object endValue) {
            Log.e("TAG","fraction==========="+fraction);
            //fraction :动画的完成进度(0-1),完成进度的速率是由插值器决定
            //startValue 开始值
            //endValue 结束值
            //返回 当前进度下,属性值
            int startWidthValue=((MyLayoutParam)startValue).getWidth();  //起始值的宽
            int startHeightValue=((MyLayoutParam)startValue).getHeight();//起始值的高
            int endWidthValue=((MyLayoutParam)endValue).getWidth();//结束值的宽
            int endHeightValue=((MyLayoutParam)endValue).getHeight();//结束值的高
            //计算当前动画进度,应该返的宽和高
            int width= (int) (startWidthValue+fraction*(endWidthValue-startWidthValue));
            int height= (int) (startHeightValue+fraction*(endHeightValue-startHeightValue));
            return new MyLayoutParam(width,height);
        }
    }
6.3、使用ValueAnimator.ofObject()开始动画属性变化
   MyLayoutParam start=new MyLayoutParam(100,100);
        MyLayoutParam end=new MyLayoutParam(200,300);
        ValueAnimator valueAnimator=  ValueAnimator.ofObject(new MyTypeEvaluator(),start,end);
        //设置动画时长
        valueAnimator.setDuration(200);
        //设置插值器 ,动画执行的速率,比如匀速,或者是先加速后减速
        valueAnimator.setInterpolator(new LinearInterpolator());
        //动画重复的次数
        valueAnimator.setRepeatCount(1);
        //动画重复的模式
        valueAnimator.setRepeatMode(ValueAnimator.RESTART);
        //设置动画执行监听,用来改变对象属性
        valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                Log.e("TAG","============="+(MyLayoutParam)animation.getAnimatedValue());
            }
        });
        valueAnimator.start();

运行输出结果:可以看到 fraction(0.0-1.0)变化规律,最终宽和高(200,300)

08-17 22:37:40.155 1950-1950/camera.test.com.animation E/TAG: fraction===========0.0
08-17 22:37:40.155 1950-1950/camera.test.com.animation E/TAG: =============camera.test.com.animation.MainActivity$MyLayoutParam@4a813a74
08-17 22:37:40.155 1950-1950/camera.test.com.animation E/TAG: fraction===========0.0
08-17 22:37:40.155 1950-1950/camera.test.com.animation E/TAG: =============camera.test.com.animation.MainActivity$MyLayoutParam@4a813a74
08-17 22:37:40.375 1950-1950/camera.test.com.animation E/TAG: fraction===========0.0
08-17 22:37:40.375 1950-1950/camera.test.com.animation E/TAG: =============camera.test.com.animation.MainActivity$MyLayoutParam@4a813a74
08-17 22:37:40.465 1950-1950/camera.test.com.animation E/TAG: fraction===========0.5
08-17 22:37:40.465 1950-1950/camera.test.com.animation E/TAG: =============camera.test.com.animation.MainActivity$MyLayoutParam@4a813a74
08-17 22:37:40.495 1950-1950/camera.test.com.animation E/TAG: fraction===========0.665
08-17 22:37:40.495 1950-1950/camera.test.com.animation E/TAG: =============camera.test.com.animation.MainActivity$MyLayoutParam@4a813a74
08-17 22:37:40.505 1950-1950/camera.test.com.animation E/TAG: fraction===========0.75
08-17 22:37:40.505 1950-1950/camera.test.com.animation E/TAG: =============camera.test.com.animation.MainActivity$MyLayoutParam@4a813a74
08-17 22:37:40.525 1950-1950/camera.test.com.animation E/TAG: fraction===========0.835
08-17 22:37:40.525 1950-1950/camera.test.com.animation E/TAG: =============camera.test.com.animation.MainActivity$MyLayoutParam@4a813a74
08-17 22:37:40.545 1950-1950/camera.test.com.animation E/TAG: fraction===========0.915
08-17 22:37:40.545 1950-1950/camera.test.com.animation E/TAG: =============camera.test.com.animation.MainActivity$MyLayoutParam@4a813a74
08-17 22:37:40.555 1950-1950/camera.test.com.animation E/TAG: fraction===========1.0
08-17 22:37:40.555 1950-1950/camera.test.com.animation E/TAG: =============camera.test.com.animation.MainActivity$MyLayoutParam@4a813a74
08-17 22:47:48.345 2016-2016/? E/TAG: fraction===========0.0
08-17 22:47:48.345 2016-2016/? E/TAG: =============width:::100---------height::::::::::100
08-17 22:47:48.375 2016-2016/? E/TAG: fraction===========0.0
08-17 22:47:48.375 2016-2016/? E/TAG: =============width:::100---------height::::::::::100
08-17 22:47:48.565 2016-2016/? E/TAG: fraction===========0.915
08-17 22:47:48.565 2016-2016/? E/TAG: =============width:::191---------height::::::::::283
08-17 22:47:48.615 2016-2016/? E/TAG: fraction===========0.16499996
08-17 22:47:48.615 2016-2016/? E/TAG: =============width:::116---------height::::::::::133
08-17 22:47:48.625 2016-2016/? E/TAG: fraction===========0.25

7、ObjectAnimator使用

7.1、ObjectAnimator.ofInt()、ofArgb()、ofFloat使用

ObjectAnimator 创建通过 ObjectAnimator.ofArgb()ObjectAnimator.ofInt()ObjectAnimator.ofFloat()ObjectAnimator.ofObject() 等方法创建

         //参数一:要改变的对象一般是View
         //参数二: 对象的属性值,可以是任意值,只要对象提供了相应的set/get方法,
        // 就可以通过属性值调用相应的get/set方法去改变属性值。
        //textView.setTranslationX();
       //参数三:可变参数开始值到结束值
      float curTranslationX = textView.getTranslationX();

        ObjectAnimator valueAnimator=ObjectAnimator.ofFloat(textView,"translationX", curTranslationX,300f);
        //设置动画时长
        valueAnimator.setDuration(2000);
        valueAnimator.setRepeatCount(2);
        valueAnimator.setRepeatMode(ValueAnimator.RESTART);
        valueAnimator.start();

ObjectAnimator.ofArgb()ObjectAnimator.ofInt()ObjectAnimator.ofArgb()都可以通过以上方法创建动画,类似只是参数类型不一样。其中属性值除了常用的,translationXtranslationYalphascaleXscaleYrotationXrotationY ,只要是对象中可以通过set/get方法获取到自定义属相都可以。

ObjectAnimatorofObject(Object target, String propertyName,TypeEvaluator evaluator, Object... values)使用给以上不一样,需除了需要传target 操作对象、propertyName 属性名称、values 变化值以外,还需要传evaluator,自定义的估值器,和之前的ValueAnimator.ofObject(TypeEvaluator evaluator, Object... values) 使用 类似。

7.2、ObjectAnimator.ofObject()使用
7.2.1、自定义View的创建

这里简单的创建一个MyTextView继承TextView ,通过改变myLayoutParam的值,来达到平移的效果,因为View中是有setTranslationXsetTranslationY 方法,这里我们封装一个能通过一个方法来完成X轴和Y轴上的平移动画。

public class MyTextView extends TextView {
    MainActivity.MyLayoutParam myLayoutParam;

    public MyTextView(Context context) {
        super(context);
    }

    public MyTextView(Context context,  AttributeSet attrs) {
        super(context, attrs);
    }

    public MyTextView(Context context,  AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }


    public MainActivity.MyLayoutParam getMyLayoutParam() {
            return myLayoutParam;
        }
        public void setMyLayoutParam(MainActivity.MyLayoutParam myLayoutParam) {
            setTranslationX(myLayoutParam.getCurTranslationX());
            setTranslationY(myLayoutParam.getCurTranslationY());
            this.myLayoutParam = myLayoutParam;
        }
}
7.2.2、MyTypeEvaluator 估值器的创建

之前已经创建过,直接拿过来用就行

class MyTypeEvaluator implements TypeEvaluator{
        @Override
        public Object evaluate(float fraction, Object startValue, Object endValue) {
            Log.e("TAG","fraction==========="+fraction);
            //fraction :动画的完成进度(0-1),完成进度的速率是由插值器决定
            //startValue 开始值
            //endValue 结束值
            //返回 当前进度下,属性值
            float startWidthValue=((MyLayoutParam)startValue).getCurTranslationX();
            float startHeightValue=((MyLayoutParam)startValue).getCurTranslationY();
            float endWidthValue=((MyLayoutParam)endValue).getCurTranslationX();
            float endHeightValue=((MyLayoutParam)endValue).getCurTranslationY();
            float width=  (startWidthValue+fraction*(endWidthValue-startWidthValue));
            float height= (startHeightValue+fraction*(endHeightValue-startHeightValue));
            return new MyLayoutParam(width,height);
        }
    }
7.2.3、MyLayoutParam 开始和结束值对象创建
 class MyLayoutParam{
        private float curTranslationY;
        private float curTranslationX;
        public MyLayoutParam(float curTranslationX, float curTranslationY) {
            this.curTranslationX = curTranslationX;
            this.curTranslationY = curTranslationY;
        }

        public float getCurTranslationY() {
            return curTranslationY;
        }

        public void setCurTranslationY(int curTranslationY) {
            this.curTranslationY = curTranslationY;
        }

        public float getCurTranslationX() {
            return curTranslationX;
        }

        public void setCurTranslationX(int curTranslationX) {
            this.curTranslationX = curTranslationX;
        }

        @Override
        public String toString() {
            return "width:::"+curTranslationX+"---------height::::::::::"+curTranslationY;
        }
    }
7.2.4、ObjectAnimator.ofObject()创建开启动画
   //参数一:要改变的对象一般是View
                //参数二: 对象的属性值,可以是任意值,只要对象提供了相应的set/get方法,
                // 就可以通过属性值调用相应的get/set方法去改变属性值。
                //textView.setTranslationX();
                //参数三:可变参数开始值到结束值
                float curTranslationX = textView.getTranslationX();
                float curTranslationY = textView.getTranslationX();

        MyLayoutParam start=new MyLayoutParam(curTranslationX,curTranslationY);
        MyLayoutParam end=new MyLayoutParam(200,300);
        ObjectAnimator valueAnimator=ObjectAnimator.ofObject(textView,"myLayoutParam",new MyTypeEvaluator(),start,end);
        //设置动画时长
        valueAnimator.setDuration(2000);
        valueAnimator.setRepeatCount(2);
        valueAnimator.setRepeatMode(ValueAnimator.RESTART);
        valueAnimator.start();

到此,属性动画的简单使用已经说完了,ObjectAnimator.ofObject()还有一些重载的方法可以继续了解下去。

发布了100 篇原创文章 · 获赞 75 · 访问量 8万+

猜你喜欢

转载自blog.csdn.net/baidu_31956557/article/details/99698364