Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android動畫總結(屬性動畫,補間動畫,幀動畫)

Android動畫總結(屬性動畫,補間動畫,幀動畫)

編輯:關於Android編程

動畫分類

Android中動畫大概分為3類:

TweenAnimation(補間動畫)

TranslateAnimation ScaleAnimation RotateAnimation AlphaAnimation

FrameAnimation(幀動畫)

PropertyAnimation(屬性動畫)

PropertyAnimation屬性動畫

先來看屬性動畫,這是潮流,也是google推薦使用的。

屬性動畫和一般的View動畫的重要區別在於:
1. 屬性動畫控制的是實實在在的屬性,但是View動畫只是產生一個動畫,並沒有改變控件的屬性。
2. View動畫只能控制View的屬性,屬性動畫可以控制所有屬性,只要這個屬性有get/set 方法,是什麼意思呢?

例如 我們查看ImageView的源碼,可以看到它有一個私有屬性叫 alpha,表示透明度,同時有 setAlpha()/getAlpha() 方法,所有我們就可以通過屬性動畫來修改ImageView的Alpha的值來完成動畫。

那麼問題來了,到底動畫是怎麼產生的呢?簡單的說就是,在動畫執行前你需要為動畫設置初始值結束值動畫時間(這是3個最基本的值),那麼ValueAnimator類就可以通過這3個值計算出一串連續的數字,表示動畫的過程。
例如:alpha值 from 0 to 255,如果時間設置成 255秒,那麼 ValueAnimator產生的值將為每秒變化1,0,1,2,3,4,5,6…,然後將這些值通過 setAlpha() 設置給ImageView,就完成了動畫。 當然這個例子比較奇葩,但是我覺得比較好理解。

那麼怎麼來實踐我說的呢?我們來看一個例子:

ValueAnimator

這是ValueAnimator的初級用法,通過 ofFloat() 方法設置起始x坐標起始x+100起始x坐標,就是一個在x軸上一個來回100px的動畫。區間是1000ms,注意為了將動畫與控件相關聯(動畫都是需要應用到控件上),需要添加一個 AnimatorUpdateListener,這個回調就是用來產生一系列的中間值,然後我們在回調中將中間值設置給我們的ImageView,那麼動畫就完成了。

最後我們還是用Log將中間值都打印了出來,就更容易理解ValueAnimator就是用來產生一個值變化的序列的作用。當然這裡使用的是默認的線性插值器,變化率是均勻的,如果使用其他插值器,還可以產生不均勻的效果。

float fromX = ivLogo.getTranslationX();
ValueAnimator va = ValueAnimator.ofFloat(fromX, fromX + 100f, fromX);
va.setDuration(1000);

va.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
    @Override
    public void onAnimationUpdate(ValueAnimator animation) {
        float v = (float) animation.getAnimatedValue();
        ivLogo.setTranslationX(v);
        Log.d(TAG, "v:" + v);
    }
});
va.start();

效果圖:

這裡寫圖片描述

打印出來的Log:

D/ANIMATION: v:0.0
D/ANIMATION: v:0.14258027
D/ANIMATION: v:0.53691864
D/ANIMATION: v:1.2311637
D/ANIMATION: v:2.2070706
D/ANIMATION: v:3.3803642
D/ANIMATION: v:4.894352
...

D/ANIMATION: v:84.35657
D/ANIMATION: v:89.65131
D/ANIMATION: v:94.66184
D/ANIMATION: v:100.0
D/ANIMATION: v:94.66184
D/ANIMATION: v:89.651306
D/ANIMATION: v:84.35657
...
D/ANIMATION: v:6.679535
D/ANIMATION: v:4.894348
D/ANIMATION: v:3.380371
D/ANIMATION: v:2.2070618
D/ANIMATION: v:1.2311707
D/ANIMATION: v:0.53691864
D/ANIMATION: v:0.14257813
D/ANIMATION: v:0.0

理解了這個,我們就可以來看看下一個更加使用的類

ObjectAnimator

public final class ObjectAnimator extends ValueAnimator{...}

查看源碼就知道,ObjectAnimator是繼承於ValueAnimator的,ObjectAnimator使用起來更加簡單,因為ValueAnimator還需要我們自己去回調,ObjectAnimator不需要寫回調,只需要把要設置的屬性,控件,區間等內容告訴它,它自己幫我們完成動畫。

例子:

float fromX = ivLogo.getTranslationX();
ObjectAnimator oa = ObjectAnimator.ofFloat(ivLogo, "translationX", fromX, fromX + 100f, fromX);
oa.setDuration(300);
oa.start();

oa.addListener(new AnimatorListenerAdapter() {
    @Override
    public void onAnimationStart(Animator animation) {
        super.onAnimationStart(animation);
    }
});

效果和使用 ValueAnimator 是一樣的,所以就不貼圖了。剛剛我們說不需要回調,但是這裡又寫了一個回調的Listener是什麼意思呢?大家大可把這個刪掉,我這裡加上主要是為了說明如果想監聽 動畫結束,動畫開始… 等中間過程,ObjectAnimator也可以做到。只需要添加這個 AnimatorListenerAdapter 抽象類。至於這裡為什麼是抽象類,大家打開源碼就可以明白,為了不實現回調的所有方法,特別加了一個抽象類實現 AnimatorListener 接口,這樣就可以想覆蓋什麼方法就覆蓋什麼方法,不需要全部都覆蓋。這也可以理解為 設計模式中的適配器模式吧,原接口不符合我的要求,我需要一個適配器來完成轉換

AnimatorSet

如果上面兩個都理解了,那麼這個就好理解了。AnimatorSet顧名思義就是動畫的集合,我們要將幾個屬性動畫放在一起運行,或者按照序列執行,或者按任意順序執行都可以實現,看看例子:

ObjectAnimator oaScaleX = ObjectAnimator.ofFloat(ivLogo, "scaleX", 0, 1);
ObjectAnimator oaScaleY = ObjectAnimator.ofFloat(ivLogo, "scaleY", 0, 1);
ObjectAnimator oaRotation = ObjectAnimator.ofFloat(ivLogo, "rotation", 0, 360);
ObjectAnimator oaAlpha = ObjectAnimator.ofFloat(ivLogo, "alpha", 1, 0);


AnimatorSet as = new AnimatorSet();
as.play(oaScaleX).with(oaScaleY).with(oaRotation);
as.play(oaAlpha).after(oaRotation);
as.setDuration(1000);
as.addListener(new AnimatorListenerAdapter() {
    @Override
    public void onAnimationEnd(Animator animation) {
        super.onAnimationEnd(animation);
        ivLogo.setAlpha(1.0f);
        Log.d(TAG, "finish:" + ivLogo.getAlpha());
    }
});
as.start();

首先構造了4個 ObjectAnimator對象,分別是沿X軸變形,沿Y軸變形,旋轉,透明度,然後我們讓前3個一起執行,之後在執行漸變,最後添加一個動畫結束回調,將Alpha設置為1,表示不透明,否則我們的控件就看不見了。

效果圖:

\

使用xml文件配置屬性動畫

android的套路,一定會允許你使用xml的方式來配置動畫,所以我們看看怎麼配置:

ba358c4d-541e-4396-bd29-135a3be2142b.png

res 文件夾下新建文件夾 animator, 然後創建一個 動畫xml文件:<喎?/kf/ware/vc/" target="_blank" class="keylink">vcD4NCjxwcmUgY2xhc3M9"brush:java;"> " data-snippet-id="ext.516fe9dd9d617d9caf45636dd4ce0cea" data-snippet-saved="false" data-codota-status="done">

android:ordering="sequentially"表示依次執行,

android:propertyName="rotation"表示修改的屬性值

android:valueType="floatType"表示屬性值類型

其他的都好理解了。

然後在代碼中使用:

Animator animator = AnimatorInflater.loadAnimator(PropertyActivity.this, R.animator.animator_1);
animator.setTarget(ivLogo);
animator.start();

效果圖:

test3.gif

使用插值器

我們知道 ValueAnimator就是用來產生一些動畫屬性中間值,但是默認是均勻變化的,插值器就是要使得產生的中間序列非均勻化,當然不僅是非均勻這麼簡單,還有很多特效:
下面是官網提供的一些插值器,大家都可以試試,我這裡只是拋磚引玉,展示最簡單的用法:

d6691284-7830-44e4-8abd-0ad2fc047b6a.png

使用方法:

float fromX = ivLogo.getTranslationX();
ObjectAnimator oa = ObjectAnimator.ofFloat(ivLogo, "translationX", fromX, fromX + 100, fromX);
oa.setInterpolator(new BounceInterpolator());
oa.setDuration(1000);
oa.start();

只比前面多了一行:oa.setInterpolator(new BounceInterpolator());

效果圖:

test4.gif

TweenAnimation補間動畫

如果上面的屬性動畫你都理解了,那麼補間動畫就更好理解了:

通過代碼,和xml配置創建Animation

btnAnimation.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        Animation animation = new TranslateAnimation(0, 200, 0, 200);
        animation.setDuration(1000);
        animation.setFillAfter(true);
        ivLogo.startAnimation(animation);
    }
});

btnXml.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        Animation animation = AnimationUtils.loadAnimation(TweenActivity.this, R.anim.anim1);
        animation.setDuration(1000);
        animation.setFillAfter(true);
        ivLogo.startAnimation(animation);
    }
});

ivLogo.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        Log.d(TAG, "onClick");
    }
});

anim1.xml




    

代碼很簡單,看一下就明白了,這裡給 ivLogo添加了一個onclick事件,是為了說明tween動畫修改的不是view的真實屬性,怎麼說呢?如果點擊第一個動畫,ivLogo的位置相對於原來的位置已經偏離到 (+200, +200) 的位置,但是這個時候如果依然點擊 ivLog原位置,依然會打印 “onClick”, 所以其實View的位置屬性是沒有變化的。所以Tween動畫修改的不是屬性值,而只是產生的一個動畫效果而已。

效果圖:

test5.gif

學習Animation的話,關注比較多的應該是Animation的一些屬性設置,大家感興趣可以參考官網。

FrameAnimation幀動畫

上面兩個動畫都與控件相關,但是幀動畫就完全是圖片的疊加。原理和 gif 動畫 或者電影一樣,是因為每一幀過的速度太快,眼睛來不及反應所以我們覺得是動畫。

anim_frame.xml



    
    
    
    
    
    
" data-snippet-id="ext.f98ecf9b620c3910fca173d8eb93cd45" data-snippet-saved="false" data-codota-status="done">

    
    
    
    
    
    
根元素為 animation-list android:oneshot=”false” 表示動畫一直循環執行

代碼調用:

btnStart.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        ivWifi.setImageResource(R.drawable.anim_frame);
        AnimationDrawable animationDrawable = (AnimationDrawable) ivWifi.getDrawable();

        if (isRun) {
            animationDrawable.stop();
        } else {
            animationDrawable.start();
        }
        isRun = !isRun;
    }
});

一個全局變量表示動畫是否在執行,然後點擊按鈕時更換狀態。

效果圖:

test6.gif

總結

Android中提供了3種動畫,以後的趨勢還是屬性動畫,所以大家不要猶豫,快來鑽研屬性動畫吧!

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved