Android Tween and Property Animation的本质区别

之前只知道这两种动画是有区别的,区别是属性动画会修改View的属性。但是具体怎么回事一直没弄明白。

在阅读了网上的各种博客和源码后,大致搞懂了区别。

Tween动画通过view的matrix和alpha变量对view进行修改,但是并不会修改view自身属性。

而Property动画会修改view的自身属性,动画结束后的效果会实实在在的反应在view上。

例子如下:

MainActivity

package com.none.objectanimatordemo;

import android.animation.Animator;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.util.Log;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.ScaleAnimation;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.Toast;


public class MainActivity extends ActionBarActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        final ImageView img = (ImageView) findViewById(R.id.id_img);
        img.setImageResource(R.mipmap.ic_launcher);
        img.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Toast.makeText(MainActivity.this, "Image", Toast.LENGTH_SHORT).show();
            }
        });
        Button btn = (Button) findViewById(R.id.id_btn);
        btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                ViewWrapper view = new ViewWrapper(img);
                AnimatorSet set = new AnimatorSet();
                ObjectAnimator width = ObjectAnimator.ofInt(view, "width", 200, 500).setDuration(3000);
                ObjectAnimator height = ObjectAnimator.ofInt(view, "height", 200, 500).setDuration(3000);
                set.playTogether(width, height);
                set.setDuration(3000).start();
                set.addListener(new Animator.AnimatorListener() {
                    @Override
                    public void onAnimationStart(Animator animation) {

                    }

                    @Override
                    public void onAnimationEnd(Animator animation) {
                        Log.d("TAG", "width: " + img.getWidth() + ", height: " + img.getHeight());
                    }

                    @Override
                    public void onAnimationCancel(Animator animation) {

                    }

                    @Override
                    public void onAnimationRepeat(Animator animation) {

                    }
                });
//                ScaleAnimation scale = new ScaleAnimation(1.0f, 4.0f, 1.0f, 4.0f, Animation.RELATIVE_TO_PARENT, 0, Animation.RELATIVE_TO_PARENT, 0);
//                scale.setFillAfter(true);
//                scale.setDuration(3000);
//                img.startAnimation(scale);
//                scale.setAnimationListener(new Animation.AnimationListener() {
//                    @Override
//                    public void onAnimationStart(Animation animation) {
//
//                    }
//
//                    @Override
//                    public void onAnimationEnd(Animation animation) {
//                        Log.d("TAG", "width: " + img.getWidth() + ", height: " + img.getHeight());
//                    }
//
//                    @Override
//                    public void onAnimationRepeat(Animation animation) {
//
//                    }
//                });

            }
        });

    }

    private static class ViewWrapper {
        public ViewWrapper(View mTarget) {
            this.mTarget = mTarget;
        }

        private View mTarget;

        private int getWidth() {
            return mTarget.getLayoutParams().width;
        }

        private void setWidth(int width) {
            mTarget.getLayoutParams().width = width;
            mTarget.requestLayout();
        }

        private int getHeight() {
            return mTarget.getLayoutParams().height;
        }

        private void setHeight(int height) {
            mTarget.getLayoutParams().height = height;
            mTarget.requestLayout();
        }

    }

}

xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <Button
        android:id="@+id/id_btn"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="@drawable/shape_circle"
        android:text="@string/hello_world" />

    <ImageView
        android:id="@+id/id_img"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:scaleType="centerCrop"/>

</LinearLayout>

可以对比打印出来的img的宽高。scale动画后img的位置并没有改变,它的宽高也没有发生变化。

property动画则渐变的修改了img的宽高,最终达到了设定值。

例子中的属性动画在修改view的宽高时,会不断的requestlayout,该函数会导致view的measure,layout,draw重复调用。


属性动画会通过反射调用预设的setter和getter函数。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值