美文网首页安卓文档
Android动画之ObjectAnimator实现补间动画和O

Android动画之ObjectAnimator实现补间动画和O

作者: sliencexiu | 来源:发表于2019-08-04 07:02 被阅读0次

    1 ObjectAnimator 概述

    前面讲解了ValueAnimator和估值器,ValueAnimator只能对数值进行计算,要实现动画需要监听动画,然后获取数值,自己操作对象。不知道大家的感觉如何,我有两个两个感觉,一是这个动画有点复杂,另一个感觉是虽然叫做属性对象,但是完全没有感受到哪里跟属性有关。本篇文章主要讲解ObjectAnimator对象,这个对象继承自ValueAnimator,可以通过改变对象的属性,实现动画,是不是感觉ObjectAnimator叫做属性对象更合适。

    ObjectAnimator继承自ValueAnimator,也是从API11才开始提供。

    ValueAnimator类提供了把动画中的属性设置给目标对象的能力,只不过需要我们设置监听自己进行设置。ObjectAnimator可以设置动画目标对象(构造函数可以直接传入),构造函数中提供了将要作用于目标对象的属性名,ObjectAnimator运行过程中会把提供的属性利用目标对象提供的set函数设置给目标对象,有时也会调用目标对象的get函数获取属性值。简单说就是ObjectAnimator通过不断控制值的变化,再不断自动赋给对象的属性(调用目标对象的setXXX函数),从而实现动画效果。

    属性动画原理:
    属性动画并不是真正通过改变对象的属性来实现动画,而是通过调用目标对象指定的setXxx方法,其中xxx就是指定的属性名,对象不一定有xxx这个属性,只要有setXxx这个方法就可以。ObjectAnimator动画过程中会调用SetXxx函数设置xxx的值,然后其内部会主动调用invalidate()函数进行不停地重绘,这样就实现了动画效果。

    ObjectAnimator类似ValueAnimator,不但可以直接利用代码生成,也可以利用xml文件实例化,xml方式不常用。
    XML定义ObjectAnimator的标签为objectAnimator,API23以后也可以使用PropertyValuesHolder,具体使用方式在讲解ValueAnimator时已经讲解,这里不再重复。

    ObjectAnimator实现动画的of方法

    ofArgb(Object target, String propertyName, int... values)
    ofArgb(T target, Property<T, Integer> property, int... values)
    ofFloat(Object target, String xPropertyName, String yPropertyName, Path path)
    ofFloat(T target, Property<T, Float> property, float... values)
    ofFloat(T target, Property<T, Float> xProperty, Property<T, Float> yProperty, Path path)
    ofFloat(Object target, String propertyName, float... values)
    
    ofInt(T target, Property<T, Integer> xProperty, Property<T, Integer> yProperty, Path path)
    ofInt(T target, Property<T, Integer> property, int... values)
    ofInt(Object target, String propertyName, int... values)
    ofInt(Object target, String xPropertyName, String yPropertyName, Path path)
    
    ofMultiFloat(Object target, String propertyName, float[][] values)
    ofMultiFloat(Object target, String propertyName, Path path)
    ofMultiFloat(Object target, String propertyName, TypeConverter<T, float[]> converter, TypeEvaluator<T> evaluator, T... values)
    ofMultiInt(Object target, String propertyName, int[][] values)
    ofMultiInt(Object target, String propertyName, Path path)
    ofMultiInt(Object target, String propertyName, TypeConverter<T, int[]> converter, TypeEvaluator<T> evaluator, T... values)
    
    ofObject(T target, Property<T, V> property, TypeEvaluator<V> evaluator, V... values)
    ofObject(Object target, String propertyName, TypeConverter<PointF, ?> converter, Path path)
    ofObject(T target, Property<T, V> property, TypeConverter<PointF, V> converter, Path path)
    ofObject(T target, Property<T, P> property, TypeConverter<V, P> converter, TypeEvaluator<V> evaluator, V... values)
    ofObject(Object target, String propertyName, TypeEvaluator evaluator, Object... values)
    
    ofPropertyValuesHolder(Object target, PropertyValuesHolder... values)
    

    2利用ObjectAnimator实现补间动画效果

    2.1 平移动画

    View有setTranslationX,setTranslationY实现坐标的改变
    setTranslationX(float translationX) :以当前控件为原点,在x轴上移动
    setTranslationY(float translationY) :以当前控件为原点,在Y轴上移动

    ObjectAnimator实现平移:
    向X轴正方向移动:

    objectAnimator = ObjectAnimator.ofFloat(textView, "translationX", 100, 200, 300,400,500);
    objectAnimator.setDuration(3000);
    objectAnimator.setInterpolator(new LinearInterpolator());
    

    Y轴方向移动不在演示

    2.2 透明度

    View有setAlpha函数控制透明度
    ObjectAnimator实现透明度变化:

    objectAnimator = ObjectAnimator.ofFloat(textView, "alpha", 0.1f,1.0f);
    objectAnimator.setDuration(3000);
    objectAnimator.setInterpolator(new LinearInterpolator());
    

    2.3 缩放

    View有setScaleX(float scaleX)和setScaleY(float scaleY)函数对View进行缩放。
    ObjectAnimator实现缩放

    objectAnimator = ObjectAnimator.ofFloat(textView, "scaleX", 0.1f,1.0f,2.0f,1.0f);
    objectAnimator.setDuration(3000);
    objectAnimator.setInterpolator(new LinearInterpolator());
    

    2.4 旋转

    View有setRotationX(float rotationX)和setRotationY(float rotationY),setRotation(rotation)函数设置旋转,
    setRotationX:绕X轴旋转
    setRotationY:绕Y轴旋转
    setRotation: 绕中心旋转

    ObjectAnimator实现旋转

    objectAnimator = ObjectAnimator.ofFloat(textView, "rotation", 0,270);
    objectAnimator.setDuration(3000);
    objectAnimator.setInterpolator(new LinearInterpolator());
    

    3 ObjectAnimator动画注意事项:重要

    总结来自:https://developer.android.google.cn/guide/topics/graphics/prop-animation#java

    动画一些特性:

    • duration 动画运行时长,如果不设置默认300ms
    • interpolation:设置动画运行过程中对应的动画完成状态(设置动画运行速率,类似动画设置了1000ms,可以让动画在运行到100ms时就展示动画完成时的状态)
    • 动画刷新频率,默认是每10ms刷新一次,但也跟系统忙碌程度有关,如果系统资源占用严重可能时间会延长。

    重要:一下内容来自androidDeveloper,非常重要请大家关注
    属性动画getXxx(),setXxx()函数和属性xxx的规则说明:

    • 如果ObjectAnimator想操作对象的foo属性实现动画操作,对象必须有相应的setFoo函数,
      因为ObjectAnimator会自动根据foo属性对应的setFoo函数去更新属性值。所以可以推测出ObjectAnimator会自动把属性转化成对应的set函数,会强制大写第一个字母,然后反射得到set函数,进行调用,所以ObjectAnimator初始化时属性首字母大小写无所谓,关键是除了首字母其他一定要和set函数对应。
    • 上面我们知道了对象setter函数的作用,那么getter函数有什么用处呢,ObjectAnimator指定values时,可以指定多个value,如果我们初始化时只指定了一个值,ObjectAnimator会把这个值作为动画结束状态的值,此时会调用getter函数作为动画初始状态的值。
    • 动画目标对象getter和setter函数的参数类型和ObjectAnimator设置动画开始和结束值的类型必须相同。
    • ObjectAnimator内部会主动调用目标对象的setter方法,但是这并不会导致view的重绘,需要你在setter方法中主动调用invalidate方法或者设置动画监听函数,在onAnimationUpdate的回调中调用invalidate方法。如果你要自己定义对象的setter方法,就要主动调用invalidate方法。

    4 自定义ObjectAnimator属性

    上面把view已经存在的平移,旋转,缩放,透明度属性利用ObjectAnimator进行了实现,接着将演示自定义ObjectAnimator属性的操作,通过上面的分析知道ObjectAnimator重要的点是属性和设置属性的set函数,以及主动调用invalidate函数,下面会通过一个例子来实现自定义ObjectAnimator属性的过程。
    自定义view

    public class ViewDemo22 extends View {
        private int color = Color.GREEN;
        private int radius = 100;
    
        private Paint mPaint;
    
        public int getColor() {
            return color;
        }
    
        public void setColor(int color) {
            this.color = color;
            mPaint.setColor(color);
            invalidate();
        }
    
        public int getRadius() {
            return radius;
        }
    
        public void setRadius(int radius) {
            this.radius = radius;
            invalidate();
        }
    
        public ViewDemo22(Context context) {
            this(context,null,0);
        }
    
        public ViewDemo22(Context context, @Nullable AttributeSet attrs) {
            this(context, attrs,0);
        }
    
        public ViewDemo22(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
            super(context, attrs, defStyleAttr);
            init();
        }
    
        private void init() {
            mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
            mPaint.setColor(color);
            mPaint.setStrokeWidth(5);
            mPaint.setStyle(Paint.Style.STROKE);
        }
    
        @Override
        protected void onDraw(Canvas canvas) {
            super.onDraw(canvas);
            canvas.drawCircle(getMeasuredHeight()/2,getMeasuredHeight()/2,radius,mPaint);
        }
    
        @Override
        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
            int width = MeasureSpec.getSize(widthMeasureSpec);
            int height = MeasureSpec.getSize(heightMeasureSpec);
            if (width < 200){
                width = 200;
            }
    
            if (height < 200){
                height = 200;
            }
    
            if (width < height){
                setMeasuredDimension(height,height);
            }else{
                setMeasuredDimension(width,width);
            }
        }
    
        @Override
        protected void onSizeChanged(int w, int h, int oldw, int oldh) {
            super.onSizeChanged(w, h, oldw, oldh);
        }
    }
    

    布局文件

    <?xml version="1.0" encoding="utf-8"?>
    <android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".MainActivity">
    
    <com.ldx.canvasdrawdemo.ViewDemo22
        android:id="@+id/viewdemo"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toBottomOf="parent"/>
    
    </android.support.constraint.ConstraintLayout>
    
    setContentView(R.layout.activity_main);
    viewDemo22 = findViewById(R.id.viewdemo);
    
    ObjectAnimator objectAnimator = ObjectAnimator.ofInt(viewDemo22, "radius", 50, 300);
    objectAnimator.setDuration(1000);
    objectAnimator.setInterpolator(new LinearInterpolator());
    objectAnimator.setRepeatCount(-1);
    objectAnimator.start();
    

    改变颜色,没有设置插值器,只是简单数据改变:

    ObjectAnimator objectAnimator = ObjectAnimator.ofInt(viewDemo22, "color", Color.RED, Color.GREEN);
    objectAnimator.setDuration(1000);
    objectAnimator.setInterpolator(new LinearInterpolator());
    objectAnimator.setRepeatCount(-1);
    objectAnimator.start();
    

    5 Xml 方式实现

    用的不多,只简单举例

    <objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
        android:duration="1000"
        android:valueTo="200"
        android:valueType="floatType"
        android:propertyName="y"
        android:repeatCount="1"
        android:repeatMode="reverse"/>
    

    ObjectAnimator objAnimator = (ObjectAnimator ) AnimatorInflater.loadAnimator(this,
    R.animator.animator);

    Animation动画概述和执行原理
    Android动画之补间动画TweenAnimation
    Android动画之逐帧动画FrameAnimation
    Android动画之插值器简介和系统默认插值器
    Android动画之插值器Interpolator自定义
    Android动画之视图动画的缺点和属性动画的引入
    Android动画之ValueAnimator用法和自定义估值器
    Android动画之ObjectAnimator实现补间动画和ObjectAnimator自定义属性
    Android动画之ObjectAnimator中ofXX函数全解析-自定义Property,TypeConverter,TypeEvaluator
    Android动画之AnimatorSet联合动画用法
    Android动画之LayoutTransition布局动画
    Android动画之共享元素动画
    Android动画之ViewPropertyAnimator(专用于view的属性动画)
    Android动画之Activity切换动画overridePendingTransition实现和Theme Xml方式实现
    Android动画之ActivityOptionsCompat概述
    Android动画之场景变换Transition动画的使用
    Android动画之Transition和TransitionManager使用
    Android动画之圆形揭露动画Circular Reveal
    Android 动画之 LayoutAnimation 动画
    Android动画之视图动画的缺点和属性动画的引入

    相关文章

      网友评论

        本文标题:Android动画之ObjectAnimator实现补间动画和O

        本文链接:https://www.haomeiwen.com/subject/mnykdctx.html