Android 屬性動(dòng)畫整理

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

傳統(tǒng)動(dòng)畫Animation

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

屬性動(dòng)畫Animator

是通過對(duì)屬性的get和set方法對(duì)屬性的真是的值進(jìn)行改變

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

s.gif

傳統(tǒng)動(dò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)在用屬性動(dòng)畫來做,代碼如下:

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

運(yùn)行結(jié)果如下:

s1.gif

屬性動(dòng)畫是真正的改變動(dòng)畫的值

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

        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),點(diǎn)擊之間的三個(gè)動(dòng)畫是同步進(jì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 類來實(shí)現(xiàn)每一個(gè)動(dòng)畫,然后在ObjectAnimator的ofPropertyValuesHolder方法傳入要用動(dòng)畫的對(duì)象,然后start開始即可..
那么這兩種方式有啥區(qū)別呢,很明顯第一種實(shí)現(xiàn)方式代碼量少,第二種方式代碼量多,本著存在即為合理的想法,肯定是第一種對(duì)內(nèi)存來耗好用比較大,第二種對(duì)內(nèi)存來說耗用比較小了.實(shí)際上Google也是這樣說的.

當(dāng)然還有第三種實(shí)現(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è)置每個(gè)子元素的添加,然后作用在一起的動(dòng)畫,運(yùn)行之后的效果和之前的是一模一樣的,此處就不貼圖了..
當(dāng)然還有按照順序來執(zhí)行,按照順序來一個(gè)個(gè)依次執(zhí)行,只需要將上方代碼中的playTogether方法替換為playSequentially即可

s3.gif

先X平移,在Y平移,最后旋轉(zhuǎn).
那么還可以怎么玩呢,還可以讓X平移和Y平移一起,它倆完了以后再來個(gè)旋轉(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

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

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

        //此種監(jiān)聽是監(jiān)聽整個(gè)動(dòng)畫的開始與結(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);
    /**
     * 一參,操作的對(duì)象
     * 二參,操作對(duì)象的屬性
     * 三參,操作對(duì)象的屬性的值變化范圍
     * 最后設(shè)置時(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   //動(dòng)畫開始
//            public void onAnimationStart(Animator animator) {
//
//            }
//
//            @Override  //動(dòng)畫結(jié)束
//            public void onAnimationEnd(Animator animator) {
//              ....do something
//            }
//
//            @Override   //動(dòng)畫取消
//            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)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市税手,隨后出現(xiàn)的幾起案子钱床,更是在濱河造成了極大的恐慌导盅,老刑警劉巖易结,帶你破解...
    沈念sama閱讀 211,042評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異花鹅,居然都是意外死亡疙赠,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,996評(píng)論 2 384
  • 文/潘曉璐 我一進(jìn)店門樊零,熙熙樓的掌柜王于貴愁眉苦臉地迎上來我磁,“玉大人,你說我怎么就攤上這事驻襟《峒瑁” “怎么了?”我有些...
    開封第一講書人閱讀 156,674評(píng)論 0 345
  • 文/不壞的土叔 我叫張陵沉衣,是天一觀的道長郁副。 經(jīng)常有香客問我,道長豌习,這世上最難降的妖魔是什么存谎? 我笑而不...
    開封第一講書人閱讀 56,340評(píng)論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮肥隆,結(jié)果婚禮上既荚,老公的妹妹穿的比我還像新娘。我一直安慰自己栋艳,他們只是感情好恰聘,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,404評(píng)論 5 384
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著嘱巾,像睡著了一般憨琳。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上旬昭,一...
    開封第一講書人閱讀 49,749評(píng)論 1 289
  • 那天篙螟,我揣著相機(jī)與錄音,去河邊找鬼问拘。 笑死遍略,一個(gè)胖子當(dāng)著我的面吹牛惧所,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播绪杏,決...
    沈念sama閱讀 38,902評(píng)論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼下愈,長吁一口氣:“原來是場噩夢(mèng)啊……” “哼!你這毒婦竟也來了蕾久?” 一聲冷哼從身側(cè)響起势似,我...
    開封第一講書人閱讀 37,662評(píng)論 0 266
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎僧著,沒想到半個(gè)月后履因,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,110評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡盹愚,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,451評(píng)論 2 325
  • 正文 我和宋清朗相戀三年栅迄,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片皆怕。...
    茶點(diǎn)故事閱讀 38,577評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡毅舆,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出愈腾,到底是詐尸還是另有隱情憋活,我是刑警寧澤,帶...
    沈念sama閱讀 34,258評(píng)論 4 328
  • 正文 年R本政府宣布顶滩,位于F島的核電站余掖,受9級(jí)特大地震影響寸爆,放射性物質(zhì)發(fā)生泄漏礁鲁。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,848評(píng)論 3 312
  • 文/蒙蒙 一赁豆、第九天 我趴在偏房一處隱蔽的房頂上張望仅醇。 院中可真熱鬧,春花似錦魔种、人聲如沸析二。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,726評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽叶摄。三九已至,卻和暖如春安拟,著一層夾襖步出監(jiān)牢的瞬間蛤吓,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,952評(píng)論 1 264
  • 我被黑心中介騙來泰國打工糠赦, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留会傲,地道東北人锅棕。 一個(gè)月前我還...
    沈念sama閱讀 46,271評(píng)論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像淌山,于是被迫代替她去往敵國和親裸燎。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,452評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容