Android属性动画

目录

属性动画

属性动画的简介

 ValueAnimator简单使用

ObjectAnimator简单使用

使用XML来编写动画


属性动画

属性动画的简介

为什么要引入属性动画?

  • 补间动画功能比较单调,只有四种动画(透明度,旋转,倾斜和位移)

  • 补间动画针对的对象只是UI控件

  • 补间动画只是改变View的显示效果,不会去改变View的属性

eg:左边的按钮移到右边,但是此时的按钮其实还停留在左边,假如你去点右面的按钮,是不会触发按钮的点击事件的~

 属性动画是什么?

  • Andoid 3.0引入,可以说是补间动画的增强版,不止可以实现四种动画效果,可以定义任何属性的变化;

  • 执行动画的对象不只是U控件。可以对任何对象执行动画(不管是否显示在屏幕上)

 属性动画相关的API

API说明
Animator创建属性动画的基类,一般不会直接用,一般用他的两个子类!
ValueAnimator上面也说了,属性动画是通过不断地修改值来实现的,而初始值和结束值间的过度动画就是由该类来负责计算的。内部采用一种时间循环的机制来计算值与值之间的动画过度,我们只需将初始值以及结束值提供给该类,并告诉它动画所需时长,该类就会自动帮我们完成从初始值平滑过渡到结束值这样的效果!除此之外,该类还负责管理动画播放次数,播放模式,以及对动画设置监听器等!
ObjectAnimatorValueAnimator的子类,允许我们对指定对象的属性执行动画,用起来更加简单,实际中用得较多。当然某些场合下,可能还是需要用到ValueAnimator
AnimatorSetAnimator的子类,用于组合多个Animator ,并制定多个Animator按照次序播放,还是同时播放
Evaluator告诉动画系统如何从初始值过度到结束值,提供了下述几种Evaluator : - IntEvaluator :用于计算int类型属性值的计算器 - FloatEvaluator :用于计算float类型属性值的计算器 - ArgbEvaluator :用于计算十六进制形式表示的颜色值的计算器 - TypeEvaluator :计算器的接口,我们可以实现该接口来完成自定义计算器

 ValueAnimator简单使用

 使用流程:

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

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

  3. 调用实例的addUpdateListener添加AnimatorUpdateListener监听器,在该监听器中 可以获得ValueAnimator计算出来的值,你可以值应用到指定对象上

  4. 调用实例的start()方法开启动画! 另外我们可以看到ofInt和ofFloat都有个这样的参数:float/int... values代表可以多个值!

代码实现

布局文件:activity_main.xml,非常简单,四个按钮,一个ImageView

<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" />
​
    <ImageView
        android:id="@+id/img_babi"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:background="@mipmap/img_pai" />
​
</LinearLayout>

接着到MainActivity.java, 首先需要一个修改View位置的方法,这里调用moveView()设置左边和上边的起始坐标以及宽高!

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

然后通过点击事件触发对应的动画

 

好的,使用的流程非常简单,先创建ValueAnimator对象,调用ValueAnimator.ofInt/ofFloat 获得,然后设置动画持续时间,addUpdateListener添加AnimatorUpdateListener事件监听, 然后使用参数animationgetAnimatedValue()获得当前的值,然后我们可以拿着这个值 来修改View的一些属性,从而形成所谓的动画效果,接着设置setInterpolator动画渲染模式, 最后调用start()开始动画的播放

ObjectAnimator简单使用

比起ValueAnimator,ObjectAnimator显得更为易用,通过该类我们可以直接 对任意对象的任意属性进行动画操作!没错,是任意对象,而不单单只是View对象, 不断地对对象中的某个属性值进行赋值,然后根据对象属性值的改变再来决定如何展现 出来!比如为TextView设置如下动画: ObjectAnimator.ofFloat(textview, "alpha", 1f, 0f); 这里就是不断改变alpha的值,从1f - 0f,然后对象根据属性值的变化来刷新界面显示,从而 展现出淡入淡出的效果,而在TextView类中并没有alpha这个属性,ObjectAnimator内部机制是: 寻找传输的属性名对应的get和set方法~,而非找这个属性值! 不信的话你可以到TextView的源码里找找是否有alpha这个属性! 好的,下面我们利用ObjectAnimator来实现四种补间动画的效果吧~

代码实现

以下代码使用了ButterKnife

public class MainActivity4 extends AppCompatActivity {
    @BindView(R.id.btn_q)
    Button btn_q;
    @BindView(R.id.btn_w)
    Button btn_w;
    @BindView(R.id.btn_e)
    Button btn_e;
    @BindView(R.id.btn_r)
    Button btn_r;
    @BindView(R.id.imageView3)
    ImageView imageView3;
    @BindView(R.id.lay_zys)
    LinearLayout lay_zys;
    @BindView(R.id.btn_t)
    Button btn_t;
    private int width;
    private int height;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main4);
        ButterKnife.bind(this);
        AnimationDrawable background = (AnimationDrawable) imageView3.getBackground();
        background.start();
    }
    private void mov(View view,int rawx,int rawy){
        int left = rawx - imageView3.getWidth();
        int top = rawy - imageView3.getHeight();
        int width = left + view.getWidth();
        int height =top+view.getHeight();
        view.layout(left,top,width,height);
    }
    @OnClick(R.id.btn_q)
    public void shuxing1(){
        btn_q.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                width=lay_zys.getWidth();
                height=lay_zys.getHeight();
                ValueAnimator va=ValueAnimator.ofInt(height,height/4,height/2,height/4*3,height);
                va.setDuration(1000l);
                va.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                    @Override
                    public void onAnimationUpdate(ValueAnimator valueAnimator) {
                        int y = (Integer) valueAnimator.getAnimatedValue();
                        int x=width/2;
                        mov(imageView3,x,y);
                    }
                });
                va.setInterpolator(new LinearInterpolator());
                va.start();
            }
        });
    }
    @OnClick(R.id.btn_w)
    public void shuxing2(){
        final float ft=0.1f;
        AnimatorSet animatorSet=new AnimatorSet();
        ValueAnimator valueAnimator=ValueAnimator.ofFloat(1.0f,ft);
        valueAnimator.setDuration(500l);
        ValueAnimator valueAnimator2=ValueAnimator.ofFloat(ft,1.0f);
        valueAnimator2.setDuration(500l);
        valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator valueAnimator) {
                float ft= (float) valueAnimator.getAnimatedValue();
                imageView3.setScaleY(ft);
                imageView3.setScaleX(ft);
            }
        });
        valueAnimator2.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator valueAnimator) {
                float ft = (float) valueAnimator.getAnimatedValue();
                imageView3.setScaleX(ft);
                imageView3.setScaleY(ft);
            }
        });
        valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator valueAnimator) {
               float ft= (float) valueAnimator.getAnimatedValue();
                imageView3.setScaleX(ft);
                imageView3.setScaleY(ft);
            }
        });
        animatorSet.play(valueAnimator2).after(valueAnimator);
        animatorSet.start();
    }
    @OnClick(R.id.btn_e)
    public void shuxing3(){
        btn_e.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                ValueAnimator valueAnimator=ValueAnimator.ofInt(0,360);
                valueAnimator.setDuration(1000l);
                valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                    @Override
                    public void onAnimationUpdate(ValueAnimator valueAnimator) {
                       int aa= (Integer) valueAnimator.getAnimatedValue();
                       imageView3.setRotation(aa);
                       float bb= valueAnimator.getAnimatedFraction();
                       imageView3.setAlpha(bb);
                    }
                });
                valueAnimator.setInterpolator(new DecelerateInterpolator());
                valueAnimator.start();
            }
        });
    }
    @OnClick(R.id.btn_r)
    public void shuxing4(){
        btn_r.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                width=lay_zys.getWidth();
                height=lay_zys.getHeight();
                final int r=width/4;
                ValueAnimator valueAnimator = ValueAnimator.ofFloat(0, (float) (2.0f * Math.PI));
                valueAnimator.setDuration(1000l);
                valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                    @Override
                    public void onAnimationUpdate(ValueAnimator valueAnimator) {
                        float ft= (float) valueAnimator.getAnimatedValue();
                        int x= (int) (r*Math.sin(ft)+width/2);
                        int y= (int) (r*Math.cos(ft)+height/2);
                        mov(imageView3,x,y);
                    }
                });
                valueAnimator.setInterpolator(new DecelerateInterpolator());
                valueAnimator.start();
            }
        });
    }
    @OnClick(R.id.btn_t)
    public void fanhui(){
        btn_t.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent intent=new Intent(MainActivity4.this,MainActivity.class);
                startActivity(intent);
            }
        });
    }
}

使用XML来编写动画

使用XML来编写动画,画的时间可能比Java代码长一点,但是重用起来就轻松很多! 对应的XML标签分别为:<animator><objectAnimator><set> 相关的属性解释如下:

  • android:ordering:指定动画的播放顺序:sequentially(顺序执行),together(同时执行)

  • android:duration:动画的持续时间

  • android:propertyName="x":这里的x,还记得上面的"alpha"吗?加载动画的那个对象里需要 定义getx和setx的方法,objectAnimator就是通过这里来修改对象里的值的!

  • android:valueFrom="1" :动画起始的初始值

  • android:valueTo="0" :动画结束的最终值

  • android:valueType="floatType":变化值的数据类型

使用例子如下

animator/property_animator.xml

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:ordering="together" >
​
    <objectAnimator
        android:duration="3000"
        android:propertyName="translationX"
        android:valueFrom="-500"
        android:valueTo="0"
        android:valueType="floatType" >
    </objectAnimator>
    <objectAnimator
        android:duration="3000"
        android:propertyName="rotation"
        android:repeatCount="3"
        android:valueFrom="0"
        android:valueTo="360"
        android:valueType="floatType" >
    </objectAnimator>
​
</set>

动画文件的加载

Animator animator = AnimatorInflater.loadAnimator(MainActivity5.this, R.animator.property_animator);
animator.setTarget(tv_show);
animator.start();

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值