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.