Android 屬性動畫整理

傳統(tǒng)動畫Animation
屬性動畫Animator

傳統(tǒng)動畫Animation

系統(tǒng)不斷的進行調(diào)用ondraw方法來實現(xiàn)重新繪制

屬性動畫Animator

是通過對屬性的get和set方法對屬性的真是的值進行改變

傳統(tǒng)動畫的局限性,只是對動畫的位置進行了改變,屬于是障眼法,但是根本的最底層的位置還是沒有改變.圖片如下,當(dāng)在初始位置點擊時候可以彈出Toast,但是在平移了之后,點擊是沒有反應(yīng)的,但是點擊最初的已經(jīng)成為空白的位置的時候,詭異的事情發(fā)生了.可以彈出Toast.

s.gif

傳統(tǒng)動畫代碼如下:

        TranslateAnimation animation = new TranslateAnimation(0, 200, 0, 0);
        animation.setDuration(1000);
        animation.setFillAfter(true);
        ImageView imageView = (ImageView) findViewById(R.id.imageView);
        imageView.startAnimation(animation);

現(xiàn)在用屬性動畫來做,代碼如下:

        /**
         * 一參,操作的對象
         * 二參,操作對象的屬性
         * 三參,操作對象的屬性的值變化范圍
         * 最后設(shè)置時間,然后start
         */
        ImageView imageView = (ImageView) findViewById(R.id.imageView);
        ObjectAnimator.ofFloat(imageView, "translationX", 0f, 200f)
                .setDuration(1000)
                .start();

運行結(jié)果如下:

s1.gif

屬性動畫是真正的改變動畫的值

既然能這么用,那就多來幾個試試效果:

        ImageView imageView = (ImageView) findViewById(R.id.imageView);
        ObjectAnimator.ofFloat(imageView, "translationX", 0f, 200f)
                .setDuration(1000)
                .start();
        ObjectAnimator.ofFloat(imageView, "translationY", 0f, 200f)
                .setDuration(1000)
                .start();
        ObjectAnimator.ofFloat(imageView, "rotation", 0f, 360f)
                .setDuration(1000)
                .start();
s2.gif

可以發(fā)現(xiàn),點擊之間的三個動畫是同步進行的.一起完成的.當(dāng)然除了用這種方法之外呢,還有一種方法:

        PropertyValuesHolder p1 = PropertyValuesHolder.ofFloat("translationX", 0f, 200f);
        PropertyValuesHolder p2 = PropertyValuesHolder.ofFloat("translationY", 0f, 200f);
        PropertyValuesHolder p3 = PropertyValuesHolder.ofFloat("rotation", 0f, 360f);
        ObjectAnimator.ofPropertyValuesHolder(imageView, p1, p2, p3).setDuration(1000).start();

通過PropertyValuesHolder 類來實現(xiàn)每一個動畫,然后在ObjectAnimator的ofPropertyValuesHolder方法傳入要用動畫的對象,然后start開始即可..
那么這兩種方式有啥區(qū)別呢,很明顯第一種實現(xiàn)方式代碼量少,第二種方式代碼量多,本著存在即為合理的想法,肯定是第一種對內(nèi)存來耗好用比較大,第二種對內(nèi)存來說耗用比較小了.實際上Google也是這樣說的.

當(dāng)然還有第三種實現(xiàn)方式:

        ObjectAnimator animator1 = ObjectAnimator.ofFloat(imageView, "translationX", 0f, 200f);
        ObjectAnimator animator2 = ObjectAnimator.ofFloat(imageView, "translationY", 0f, 200f);
        ObjectAnimator animator3 = ObjectAnimator.ofFloat(imageView, "rotation", 0f, 360f);
        AnimatorSet set = new AnimatorSet();
        set.playTogether(animator1,animator2,animator3);
        set.setDuration(1000);
        set.start();

就是用set集合去設(shè)置每個子元素的添加,然后作用在一起的動畫,運行之后的效果和之前的是一模一樣的,此處就不貼圖了..
當(dāng)然還有按照順序來執(zhí)行,按照順序來一個個依次執(zhí)行,只需要將上方代碼中的playTogether方法替換為playSequentially即可

s3.gif

先X平移,在Y平移,最后旋轉(zhuǎn).
那么還可以怎么玩呢,還可以讓X平移和Y平移一起,它倆完了以后再來個旋轉(zhuǎn)

        ObjectAnimator animator1 = ObjectAnimator.ofFloat(imageView, "translationX", 0f, 200f);
        ObjectAnimator animator2 = ObjectAnimator.ofFloat(imageView, "translationY", 0f, 200f);
        ObjectAnimator animator3 = ObjectAnimator.ofFloat(imageView, "rotation", 0f, 360f);
        AnimatorSet set = new AnimatorSet();
//        set.playSequentially(animator1,animator2,animator3);
        set.play(animator1).with(animator2);
        set.play(animator3).after(animator1);
        set.setDuration(1000);
        set.start();
s4.gif

接下來,搞一下屬性動畫的監(jiān)聽;

 public void click(View view) {
        ObjectAnimator animator = ObjectAnimator.ofFloat(view, "alpha", 0f, 1f);
        animator.setDuration(1000);
        //此種監(jiān)聽是通過adapter來實現(xiàn)動畫執(zhí)行的過程的中的某一個階段的監(jiān)聽
        animator.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                super.onAnimationEnd(animation);
                // TODO: 2017/1/20
            }
        });

        //此種監(jiān)聽是監(jiān)聽整個動畫的開始與結(jié)束以及取消和重復(fù)的模式等監(jiān)聽
        animator.addListener(new Animator.AnimatorListener() {
            @Override
            public void onAnimationStart(Animator animator) {
                // TODO: 
            }

            @Override
            public void onAnimationEnd(Animator animator) {
                // TODO: 
            }

            @Override
            public void onAnimationCancel(Animator animator) {
                // TODO:
            }

            @Override
            public void onAnimationRepeat(Animator animator) {
                // TODO: 
            }
        });

    }

衛(wèi)星菜單:

package com.ccstest.activity;

import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.animation.PropertyValuesHolder;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.view.animation.BounceInterpolator;
import android.view.animation.TranslateAnimation;
import android.widget.ImageView;
import android.widget.Toast;

import com.ccstest.R;

import java.util.ArrayList;
import java.util.List;

public class AnimActivity extends AppCompatActivity implements View.OnClickListener {

    private int[] res = {R.id.imageView_a, R.id.imageView_b, R.id.imageView_c, R.id.imageView_d,
            R.id.imageView_e, R.id.imageView_f, R.id.imageView_g, R.id.imageView_h};
    private List<ImageView> mImageViews = new ArrayList<>();
    private boolean flag = true;


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

        for (int i = 0; i < res.length; i++) {
            ImageView img = (ImageView) findViewById(res[i]);
            img.setOnClickListener(this);
            mImageViews.add(img);
        }
    }

    @Override
    public void onClick(View view) {
        switch (view.getId()) {
            case R.id.imageView_a:
                if (flag) {
                    startAnim();
                } else {
                    closeAnim();
                }
                break;
            default:
                Toast.makeText(AnimActivity.this, "click = " + view.getId(), Toast.LENGTH_SHORT).show();
                break;
        }
    }

    private void closeAnim() {
        for (int i = 0; i < res.length; i++) {
            ObjectAnimator animator = ObjectAnimator.ofFloat(mImageViews.get(i), "translationY", i * 200, 0);
            animator.setDuration(500);
            animator.setStartDelay(i * 100);
            animator.setInterpolator(new BounceInterpolator());
            animator.start();
            flag = true;
        }

    }

    private void startAnim() {
        for (int i = 0; i < res.length; i++) {
            ObjectAnimator animator = ObjectAnimator.ofFloat(mImageViews.get(i), "translationY", 0f, i * 300);
            animator.setDuration(500);
            animator.setInterpolator(new BounceInterpolator());
            animator.setStartDelay(i * 100);
            animator.start();
            flag = false;
        }


    }

//    public void click(View view) {
//        Toast.makeText(this, "clicked", Toast.LENGTH_SHORT).show();
//    }
//
//    public void move(View view) {
//        TranslateAnimation animation = new TranslateAnimation(0, 200, 0, 0);
//        animation.setDuration(1000);
//        animation.setFillAfter(true);
//        ImageView imageView = (ImageView) findViewById(R.id.imageView);
//        imageView.startAnimation(animation);
    /**
     * 一參,操作的對象
     * 二參,操作對象的屬性
     * 三參,操作對象的屬性的值變化范圍
     * 最后設(shè)置時間,然后start
     */
//        ImageView imageView = (ImageView) findViewById(R.id.imageView);
//        ObjectAnimator.ofFloat(imageView, "translationX", 0f, 200f)
//                .setDuration(1000)
//                .start();
//        ObjectAnimator.ofFloat(imageView, "translationY", 0f, 200f)
//                .setDuration(1000)
//                .start();
//        ObjectAnimator.ofFloat(imageView, "rotation", 0f, 360f)
//                .setDuration(1000)
//                .start();

//        PropertyValuesHolder p1 = PropertyValuesHolder.ofFloat("translationX", 0f, 200f);
//        PropertyValuesHolder p2 = PropertyValuesHolder.ofFloat("translationY", 0f, 200f);
//        PropertyValuesHolder p3 = PropertyValuesHolder.ofFloat("rotation", 0f, 360f);
//        ObjectAnimator.ofPropertyValuesHolder(imageView, p1, p2, p3).setDuration(1000).start();

//        ObjectAnimator animator1 = ObjectAnimator.ofFloat(imageView, "translationX", 0f, 200f);
//        ObjectAnimator animator2 = ObjectAnimator.ofFloat(imageView, "translationY", 0f, 200f);
//        ObjectAnimator animator3 = ObjectAnimator.ofFloat(imageView, "rotation", 0f, 360f);
//        AnimatorSet set = new AnimatorSet();
//        set.playSequentially(animator1,animator2,animator3);
//        set.play(animator1).with(animator2);
//        set.play(animator3).after(animator1);
//        set.setDuration(1000);
//        set.start();
//        ObjectAnimator animator = ObjectAnimator.ofFloat(view, "alpha", 0f, 1f);
//        animator.setDuration(1000);
//        animator.addListener(new AnimatorListenerAdapter() {
//            @Override
//            public void onAnimationEnd(Animator animation) {
//                super.onAnimationEnd(animation);
//                //....do something
//            }
//        });
//        animator.addListener(new Animator.AnimatorListener() {
//            @Override   //動畫開始
//            public void onAnimationStart(Animator animator) {
//
//            }
//
//            @Override  //動畫結(jié)束
//            public void onAnimationEnd(Animator animator) {
//              ....do something
//            }
//
//            @Override   //動畫取消
//            public void onAnimationCancel(Animator animator) {
//
//            }
//
//            @Override   //重復(fù)模式
//            public void onAnimationRepeat(Animator animator) {
//
//            }
//        });
//        animator.start();
//
//    }


}

package com.ccstest.activity;

import android.animation.TypeEvaluator;
import android.animation.ValueAnimator;
import android.graphics.PointF;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;

import com.ccstest.R;

public class AnimTimeActivity extends AppCompatActivity {

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

    public void animTiem(View view){
//        final Button button = (Button) view;
//        ValueAnimator animator = ValueAnimator.ofInt(0, 100);
//        animator.setDuration(5000);
//        animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
//            @Override
//            public void onAnimationUpdate(ValueAnimator valueAnimator) {
//                Integer value = (Integer) valueAnimator.getAnimatedValue();
//                button.setText(value+"");
//            }
//        });
//        animator.start();
        ValueAnimator animator = ValueAnimator.ofObject(new TypeEvaluator<PointF>() {
            @Override
            public PointF evaluate(float v, PointF pointF, PointF t1) {
                return null;
            }
        });
    }


}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容