Android Property Animation 属性动画

属性动画 (Property Animation) 是通过不断的修改值来实现的,而初始值和结束值间的过渡动画就是由 ValueAnimator 来负责计算

ValueAnimator 动画采用一种时间循环的机制来计算值与值之间的动画过度,我们只要设定初始值和结束值,并设定动画运行时长就可以了,它会自动帮我们完成从初始值平滑过度到结束值这样的效果

除了上面说的外,ValueAnimator 还负责管理动画的次数,播放模式,以及对动画设置监听器等

属性动画相关的类

Animator

创建属性动画的基类,一般不会直接用,用它的两个子类

ValueAnimator

属性动画的管理类,会自动补间初始值与结束值之间的过渡效果

ObjectAnimator

`ValueAnimator` 的子类,允许我们对指定对象的属性执行动画

AnimatorSet

`Animator` 的子类,用于组合多个 `Animator`,并指定多个 `Animator` 是按照顺序播放还是同时播放

Evaluator (计算器)

该类用于告诉动画系统如何从初始值过度到结束值

ValueAnimator 的使用流程

  1. 调用 ValueAnimator 的静态方法 ofInt(),ofFloat() 或 ofObject() 静态方法创建 ValueAnimator 实例

  2. 调用实例的 setXxx 方法设置动画持续时间,插值方式,重复次数等

  3. 调用实例的 addUpdateListener() 添加 AnimatorUpdateListener 监听器,在该监听器中 可以获得 ValueAnimator 计算出来的值

  4. 调用实例的 start() 方法开启动画

ofInt() 、 ofFloat() 、 ofObject() 可以传入多个相同的参数

范例

我们写一个 demo 使用 ValueAnimator 来实现四种补间动画的效果


  1. 创建一个 空的 Android 项目 cn.twle.android.ValueAnimator

  2. 修改 activity_main.xml 布局

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/ly_root"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">
    
        <Button
            android:id="@+id/btn_one"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="动画1" />
    
        <Button
            android:id="@+id/btn_two"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="动画2" />
    
        <Button
            android:id="@+id/btn_three"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="动画3" />
    
        <Button
            android:id="@+id/btn_four"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="动画4" />
    
        <TextView
            android:id="@+id/ms_text"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:text="简单教程,简单编程" />
    
    </LinearLayout>
    
  3. 修改 MainActivity.java

    定义了四个动画,分别是:直线移动,缩放,旋转加透明,以及圆形旋转

    package cn.twle.android.valueanimator;
    
    import android.animation.AnimatorSet;
    import android.animation.ValueAnimator;
    import android.support.v7.app.AppCompatActivity;
    import android.os.Bundle;
    import android.view.View;
    import android.view.animation.DecelerateInterpolator;
    import android.view.animation.LinearInterpolator;
    import android.widget.Button;
    import android.widget.LinearLayout;
    import android.widget.TextView;
    import android.widget.Toast;
    
    public class MainActivity extends AppCompatActivity implements View.OnClickListener {
    
        private Button btn_one;
        private Button btn_two;
        private Button btn_three;
        private Button btn_four;
        private LinearLayout ly_root;
        private TextView ms_text;
        private int width;
        private int height;
    
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            bindViews();
        }
    
        private void bindViews() {
            ly_root = (LinearLayout) findViewById(R.id.ly_root);
            btn_one = (Button) findViewById(R.id.btn_one);
            btn_two = (Button) findViewById(R.id.btn_two);
            btn_three = (Button) findViewById(R.id.btn_three);
            btn_four = (Button) findViewById(R.id.btn_four);
            ms_text = (TextView) findViewById(R.id.ms_text);
    
            btn_one.setOnClickListener(this);
            btn_two.setOnClickListener(this);
            btn_three.setOnClickListener(this);
            btn_four.setOnClickListener(this);
        }
    
        @Override
        public void onClick(View v) {
            switch (v.getId()) {
                case R.id.btn_one:
                    lineAnimator();
                    break;
                case R.id.btn_two:
                    scaleAnimator();
                    break;
                case R.id.btn_three:
                    raAnimator();
                    break;
                case R.id.btn_four:
                    circleAnimator();
                    break;
            }
        }
    
        //定义一个修改ImageView位置的方法
        private void moveView(View view, int rawX, int rawY) {
            int left = rawX - ms_text.getWidth() / 2;
            int top = rawY - ms_text.getHeight();
            int width = left + view.getWidth();
            int height = top + view.getHeight();
            view.layout(left, top, width, height);
        }
    
        //定义属性动画的方法:
    
        //按轨迹方程来运动
        private void lineAnimator() {
            width = ly_root.getWidth();
            height = ly_root.getHeight();
            ValueAnimator xValue = ValueAnimator.ofInt(height,0,height / 4,height / 2,height / 4 * 3 ,height);
            xValue.setDuration(3000L);
            xValue.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                @Override
                public void onAnimationUpdate(ValueAnimator animation) {
                    // 轨迹方程 x = width / 2
                    int y = (Integer) animation.getAnimatedValue();
                    int x = width / 2;
                    moveView(ms_text, x, y);
                }
            });
            xValue.setInterpolator(new LinearInterpolator());
            xValue.start();
        }
    
        //缩放效果
        private void scaleAnimator(){
    
            //这里故意用两个是想让大家体会下组合动画怎么用而已~
            final float scale = 0.5f;
            AnimatorSet scaleSet = new AnimatorSet();
            ValueAnimator valueAnimatorSmall = ValueAnimator.ofFloat(1.0f, scale);
            valueAnimatorSmall.setDuration(500);
    
            ValueAnimator valueAnimatorLarge = ValueAnimator.ofFloat(scale, 1.0f);
            valueAnimatorLarge.setDuration(500);
    
            valueAnimatorSmall.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                @Override
                public void onAnimationUpdate(ValueAnimator animation) {
                    float scale = (Float) animation.getAnimatedValue();
                    ms_text.setScaleX(scale);
                    ms_text.setScaleY(scale);
                }
            });
            valueAnimatorLarge.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                @Override
                public void onAnimationUpdate(ValueAnimator animation) {
                    float scale = (Float) animation.getAnimatedValue();
                    ms_text.setScaleX(scale);
                    ms_text.setScaleY(scale);
                }
            });
    
            scaleSet.play(valueAnimatorLarge).after(valueAnimatorSmall);
            scaleSet.start();
    
            //其实可以一个就搞定的
    //        ValueAnimator vValue = ValueAnimator.ofFloat(1.0f, 0.6f, 1.2f, 1.0f, 0.6f, 1.2f, 1.0f);
    //        vValue.setDuration(1000L);
    //        vValue.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
    //            @Override
    //            public void onAnimationUpdate(ValueAnimator animation) {
    //                float scale = (Float) animation.getAnimatedValue();
    //                ms_text.setScaleX(scale);
    //                ms_text.setScaleY(scale);
    //            }
    //        });
    //        vValue.setInterpolator(new LinearInterpolator());
    //        vValue.start();
        }
    
        //旋转的同时透明度变化
        private void raAnimator(){
            ValueAnimator rValue = ValueAnimator.ofInt(0, 360);
            rValue.setDuration(1000L);
            rValue.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                @Override
                public void onAnimationUpdate(ValueAnimator animation) {
                    int rotateValue = (Integer) animation.getAnimatedValue();
                    ms_text.setRotation(rotateValue);
                    float fractionValue = animation.getAnimatedFraction();
                    ms_text.setAlpha(fractionValue);
                }
            });
            rValue.setInterpolator(new DecelerateInterpolator());
            rValue.start();
        }
    
        //圆形旋转
        protected void circleAnimator() {
            width = ly_root.getWidth();
            height = ly_root.getHeight();
            final int R = width / 4;
            ValueAnimator tValue = ValueAnimator.ofFloat(0,
                    (float) (2.0f * Math.PI));
            tValue.setDuration(1000);
            tValue.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                @Override
                public void onAnimationUpdate(ValueAnimator animation) {
                    // 圆的参数方程 x = R * sin(t) y = R * cos(t)
                    float t = (Float) animation.getAnimatedValue();
                    int x = (int) (R * Math.sin(t) + width / 2);
                    int y = (int) (R * Math.cos(t) + height / 2);
                    moveView(ms_text, x, y);
                }
            });
            tValue.setInterpolator(new DecelerateInterpolator());
            tValue.start();
        }
    }
    

Android 基础教程

关于   |   FAQ   |   我们的愿景   |   广告投放   |  博客

♥   简单教程,简单编程 - IT 入门首选站

Copyright © 2013-2022 简单教程 twle.cn All Rights Reserved.