天天看點

android彈球動畫,Android 卡通片(anim)詳解

最後一點是SDK中提到的,不要在onCreate中調用start,因為AnimationDrawable還沒有完全跟Window相關聯,如果想要界面顯示時就開始動畫的話,可以在onWindowFoucsChanged()中調用start()。

3. Property Animation

屬性動畫,這個是在Android 3.0中才引進的,它更改的是對象的實際屬性,在View Animation(Tween Animation)中,其改變的是View的繪制效果,真正的View的屬性保持不變,比如無論你在對話中如何縮放Button的大小,Button的有效點選區域還是沒有應用動畫時的區域,其位置與大小都不變。而在Property Animation中,改變的是對象的實際屬性,如Button的縮放,Button的位置與大小屬性值都改變了。而且Property Animation不止可以應用于View,還可以應用于任何對象。Property

Animation隻是表示一個值在一段時間内的改變,當值改變時要做什麼事情完全是你自己決定的。

在Property Animation中,可以對動畫應用以下屬性:

Duration:動畫的持續時間

TimeInterpolation:屬性值的計算方式,如先快後慢

TypeEvaluator:根據屬性的開始、結束值與TimeInterpolation計算出的因子計算出目前時間的屬性值

Repeat Count and behavoir:重複次數與方式,如播放3次、5次、無限循環,可以此動畫一直重複,或播放完時再反向播放

Animation sets:動畫集合,即可以同時對一個對象應用幾個動畫,這些動畫可以同時播放也可以對不同動畫設定不同開始偏移

Frame refreash delay:多少時間重新整理一次,即每隔多少時間計算一次屬性值,預設為10ms,最終重新整理時間還受系統程序排程與硬體的影響

Interpolator

首先要了解為什麼需要插值器,因為在補間動畫中,我們一般隻定義關鍵幀(首幀或尾幀),然後由系統自動生成中間幀,生成中間幀的這個過程可以成為“插值”。插值器定義了動畫變化的速率,提供不同的函數定義變化值相對于時間的變化規則,可以定義各種各樣的非線性變化函數,比如加速、減速等。下面是幾種常見的插值器:

Interpolator對象

資源ID

功能作用

AccelerateDecelerateInterpolator

@android:anim/accelerate_decelerate_interpolator

先加速再減速

AccelerateInterpolator

@android:anim/accelerate_interpolator

加速

AnticipateInterpolator

@android:anim/anticipate_interpolator

先回退一小步然後加速前進

AnticipateOvershootInterpolator

@android:anim/anticipate_overshoot_interpolator

在上一個基礎上超出終點一小步再回到終點

BounceInterpolator

@android:anim/bounce_interpolator

最後階段彈球效果

CycleInterpolator

@android:anim/cycle_interpolator

周期運動

DecelerateInterpolator

@android:anim/decelerate_interpolator

減速

LinearInterpolator

@android:anim/linear_interpolator

勻速

OvershootInterpolator

@android:anim/overshoot_interpolator

快速到達終點并超出一小步最後回到終點

如果隻簡單地引用這些插值器還不能滿足需要的話,我們要考慮一下個性化插值器。我們可以建立一個插值器資源修改插值器的屬性,比如修改AnticipateInterpolator的加速速率,調整CycleInterpolator的循環次數等。為了完成這種需求,我們需要建立XML資源檔案,然後将其放于/res/anim下,然後再動畫元素中引用即可。我們先來看一下幾種常見的插值器可調整的屬性:

android:factor 浮點值,加速速率,預設為1

android:tension 浮點值,起始點後退的張力、拉力數,預設為2

android:tension 同上 android:extraTension 浮點值,拉力的倍數,預設為1.5(2 * 1.5)

android:cycles 整數值,循環的個數,預設為1

android:factor 浮點值,減速的速率,預設為1

浮點值,超出終點後的張力、拉力,預設為2

下面我們就拿最後一個插值器來舉例:

android:tension="7.0"/>

上面的代碼中,我們把張力改為7.0,然後将此檔案命名為my_overshoot_interpolator.xml,放置于/res/anim下,我們就可以引用到自定義的插值器了:

android:interpolator="@anim/my_overshoot_interpolator"

.../>

AccelerateDecelerateInterpolator

public class AccelerateDecelerateInterpolator implements Interpolator {

public AccelerateDecelerateInterpolator() {

}

@SuppressWarnings({"UnusedDeclaration"})

public AccelerateDecelerateInterpolator(Context context, AttributeSet attrs) {

}

public float getInterpolation(float input) {

return (float)(Math.cos((input + 1) * Math.PI) / 2.0f) + 0.5f;

}

}

android彈球動畫,Android 卡通片(anim)詳解

AccelerateInterpolator

public class AccelerateInterpolator implements Interpolator {

private final float mFactor;

private final double mDoubleFactor;

public AccelerateInterpolator() {

mFactor = 1.0f;

mDoubleFactor = 2.0;

}

public AccelerateInterpolator(float factor) {

mFactor = factor;

mDoubleFactor = 2 * mFactor;

}

public AccelerateInterpolator(Context context, AttributeSet attrs) {

TypedArray a =

context.obtainStyledAttributes(attrs, com.android.internal.R.styleable.AccelerateInterpolator);

mFactor = a.getFloat(com.android.internal.R.styleable.AccelerateInterpolator_factor, 1.0f);

mDoubleFactor = 2 * mFactor;

a.recycle();

}

public float getInterpolation(float input) {

if (mFactor == 1.0f) {

return input * input;

} else {

return (float)Math.pow(input, mDoubleFactor);

}

}

}

android彈球動畫,Android 卡通片(anim)詳解

AnticipateInterpolator

public class AnticipateInterpolator implements Interpolator {

private final float mTension;

public AnticipateInterpolator() {

mTension = 2.0f;

}

public AnticipateInterpolator(float tension) {

mTension = tension;

}

public AnticipateInterpolator(Context context, AttributeSet attrs) {

TypedArray a = context.obtainStyledAttributes(attrs,

com.android.internal.R.styleable.AnticipateInterpolator);

mTension =

a.getFloat(com.android.internal.R.styleable.AnticipateInterpolator_tension, 2.0f);

a.recycle();

}

public float getInterpolation(float t) {

// a(t) = t * t * ((tension + 1) * t - tension)

return t * t * ((mTension + 1) * t - mTension);

}

}

android彈球動畫,Android 卡通片(anim)詳解

AnticipateOvershootInterpolator

public class AnticipateOvershootInterpolator implements Interpolator {

private final float mTension;

public AnticipateOvershootInterpolator() {

mTension = 2.0f * 1.5f;

}

public AnticipateOvershootInterpolator(float tension) {

mTension = tension * 1.5f;

}

public AnticipateOvershootInterpolator(float tension, float extraTension) {

mTension = tension * extraTension;

}

public AnticipateOvershootInterpolator(Context context, AttributeSet attrs) {

TypedArray a = context.obtainStyledAttributes(attrs, AnticipateOvershootInterpolator);

mTension = a.getFloat(AnticipateOvershootInterpolator_tension, 2.0f) *

a.getFloat(AnticipateOvershootInterpolator_extraTension, 1.5f);

a.recycle();

}

private static float a(float t, float s) {

return t * t * ((s + 1) * t - s);

}

private static float o(float t, float s) {

return t * t * ((s + 1) * t + s);

}

public float getInterpolation(float t) {

// a(t, s) = t * t * ((s + 1) * t - s)

// o(t, s) = t * t * ((s + 1) * t + s)

// f(t) = 0.5 * a(t * 2, tension * extraTension), when t < 0.5

// f(t) = 0.5 * (o(t * 2 - 2, tension * extraTension) + 2), when t <= 1.0

if (t < 0.5f) return 0.5f * a(t * 2.0f, mTension);

else return 0.5f * (o(t * 2.0f - 2.0f, mTension) + 2.0f);

}

}

android彈球動畫,Android 卡通片(anim)詳解

BounceInterpolator

public class BounceInterpolator implements Interpolator {

public BounceInterpolator() {

}

@SuppressWarnings({"UnusedDeclaration"})

public BounceInterpolator(Context context, AttributeSet attrs) {

}

private static float bounce(float t) {

return t * t * 8.0f;

}

public float getInterpolation(float t) {

// _b(t) = t * t * 8

// bs(t) = _b(t) for t < 0.3535

// bs(t) = _b(t - 0.54719) + 0.7 for t < 0.7408

// bs(t) = _b(t - 0.8526) + 0.9 for t < 0.9644

// bs(t) = _b(t - 1.0435) + 0.95 for t <= 1.0

// b(t) = bs(t * 1.1226)

t *= 1.1226f;

if (t < 0.3535f) return bounce(t);

else if (t < 0.7408f) return bounce(t - 0.54719f) + 0.7f;

else if (t < 0.9644f) return bounce(t - 0.8526f) + 0.9f;

else return bounce(t - 1.0435f) + 0.95f;

}

}

android彈球動畫,Android 卡通片(anim)詳解

CycleInterpolator

public class CycleInterpolator implements Interpolator {

public CycleInterpolator(float cycles) {

mCycles = cycles;

}

public CycleInterpolator(Context context, AttributeSet attrs) {

TypedArray a =

context.obtainStyledAttributes(attrs, com.android.internal.R.styleable.CycleInterpolator);

mCycles = a.getFloat(com.android.internal.R.styleable.CycleInterpolator_cycles, 1.0f);

a.recycle();

}

public float getInterpolation(float input) {

return (float)(Math.sin(2 * mCycles * Math.PI * input));

}

private float mCycles;

}

參數為2時的曲線:

android彈球動畫,Android 卡通片(anim)詳解

DecelerateInterpolator

public class DecelerateInterpolator implements Interpolator {

public DecelerateInterpolator() {

}

public DecelerateInterpolator(float factor) {

mFactor = factor;

}

public DecelerateInterpolator(Context context, AttributeSet attrs) {

TypedArray a =

context.obtainStyledAttributes(attrs, com.android.internal.R.styleable.DecelerateInterpolator);

mFactor = a.getFloat(com.android.internal.R.styleable.DecelerateInterpolator_factor, 1.0f);

a.recycle();

}

public float getInterpolation(float input) {

float result;

if (mFactor == 1.0f) {

result = (float)(1.0f - (1.0f - input) * (1.0f - input));

} else {

result = (float)(1.0f - Math.pow((1.0f - input), 2 * mFactor));

}

return result;

}

private float mFactor = 1.0f;

}

android彈球動畫,Android 卡通片(anim)詳解

LinearInterpolator

public class LinearInterpolator implements Interpolator {

public LinearInterpolator() {

}

public LinearInterpolator(Context context, AttributeSet attrs) {

}

public float getInterpolation(float input) {

return input;

}

}

android彈球動畫,Android 卡通片(anim)詳解

OvershootInterpolator

public class OvershootInterpolator implements Interpolator {

private final float mTension;

public OvershootInterpolator() {

mTension = 2.0f;

}

public OvershootInterpolator(float tension) {

mTension = tension;

}

public OvershootInterpolator(Context context, AttributeSet attrs) {

TypedArray a = context.obtainStyledAttributes(attrs,

com.android.internal.R.styleable.OvershootInterpolator);

mTension =

a.getFloat(com.android.internal.R.styleable.OvershootInterpolator_tension, 2.0f);

a.recycle();

}

public float getInterpolation(float t) {

// _o(t) = t * t * ((tension + 1) * t + tension)

// o(t) = _o(t - 1) + 1

t -= 1.0f;

return t * t * ((mTension + 1) * t + mTension) + 1.0f;

}

}

android彈球動畫,Android 卡通片(anim)詳解