三、核心接口
1、AnimationListener
/*** <p>An animation listener receives notifications from an animation.
* Notifications indicate animation related events, such as the end or the
* repetition of the animation.</p>
*/
public static interface AnimationListener {
void onAnimationStart(Animation animation);
void onAnimationEnd(Animation animation);
void onAnimationRepeat(Animation animation);
}
爲動畫設置監聽,看具體方法名稱就可以知道;可以實現該監聽接口,在動畫開始時,動畫結束時,動畫重複時加入自己的邏輯實現。使用很簡單,不再贅述。
2、Interpolator
Interpolator 被用來修飾動畫效果,定義動畫的變化率,實現accelerated(加速),decelerated(減速),repeated(重複),bounced(彈跳)等效果。
從API 11開始,所有的Interpolator都是從TimeInterpolator接口派生來的。TimeInterpolator只定義了一個方法:
public abstract float getInterpolation(float input);
public abstract float getInterpolation(float input);
輸入值是0.0-1.0的浮點數,表示動畫的進度。0.0表示開始,1.0表示結束。返回值是輸入值的函數,值域也在0.0-1.0中。
Interpolator 接口實現了TimeInterpolator接口,但是並沒有添加新的 方法。Interpolator接口在API11之前就有了,只是繼承關係不同罷了。
從API 22開始,增加了BaseInterpolator抽象類的實現。
Andorid爲我們實現了幾種常用的差值器,包括:
LinearInterpolator 以常量速率改變
AccelerateInterpolator 在動畫開始的地方速率改變比較慢,然後開始加速
DecelerateInterpolator 在動畫開始的地方快然後慢
AccelerateDecelerateInterpolator 在動畫開始與結束的地方速率改變比較慢,在中間的時候加速
AnticipateInterpolator 開始的時候向後然後向前甩
AnticipateOvershootInterpolator 開始的時候向後然後向前甩一定值後返回最後的值
BounceInterpolator 動畫結束的時候彈起
CycleInterpolator 動畫循環播放特定的次數,速率改變沿着正弦曲線
OvershootInterpolator 向前甩一定值後再回到原來位置
AnticipateInterpolator 開始的時候向後然後向前甩
AnticipateOvershootInterpolator 開始的時候向後然後向前甩一定值後返回最後的值
BounceInterpolator 動畫結束的時候彈起
CycleInterpolator 動畫循環播放特定的次數,速率改變沿着正弦曲線
OvershootInterpolator 向前甩一定值後再回到原來位置
下面從源碼的角度來分析下這些常用的插值器:
(1)LinearInterpolator://這個最簡單,是線性變化的,不再給出圖示
(1)LinearInterpolator://這個最簡單,是線性變化的,不再給出圖示
public float getInterpolation(float input){
return input;
}
(2)AccelerateInterpolator
構造時可以指定係數,當係數爲1.0f時,效果爲y=x^2的拋物線,非1.0f時,則爲x的係數次方,可以爲非整數。實現加速效果。
/**
* An interpolator where the rate of change starts out slowly and
* and then accelerates.
*
*/
public class AccelerateInterpolator implements Interpolator {
private final float mFactor;
private final double mDoubleFactor;
public AccelerateInterpolator() {
mFactor = 1.0f;
mDoubleFactor = 2.0;
}
/**
* Constructor
*
* @param factor Degree to which the animation should be eased. Seting
* factor to 1.0f produces a y=x^2 parabola. Increasing factor above
* 1.0f exaggerates the ease-in effect (i.e., it starts even
* slower and ends evens faster)
*/
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);
}
}
}
(3)DecelerateInterpolator 1.0f時,產生倒過來的y=x^2拋物線。實現減速效果;。
/**
* An interpolator where the rate of change starts out quickly and
* and then decelerates.
*
*/
public class DecelerateInterpolator implements Interpolator {
public DecelerateInterpolator() {
}
/**
* Constructor
*
* @param factor Degree to which the animation should be eased. Setting factor to 1.0f produces
* an upside-down y=x^2 parabola. Increasing factor above 1.0f makes exaggerates the
* ease-out effect (i.e., it starts even faster and ends evens slower)
*/
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;
}
(4)AccelerateDecelerateInterpolator
以0.5爲界,先快後慢。
/**
* An interpolator where the rate of change starts and ends slowly but
* accelerates through the middle.
*
*/
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;
}
}
(5)AnticipateInterpolator
張力的效果。這個是開始的時候向後,然後向前甩的效果。公式:a(t) = t * t * ((tension + 1) * t - tension)。
/**
* An interpolator where the change starts backward then flings forward.
*/
public class AnticipateInterpolator implements Interpolator {
private final float mTension;
public AnticipateInterpolator() {
mTension = 2.0f;
}
/**
* @param tension Amount of anticipation. When tension equals 0.0f, there is
* no anticipation and the interpolator becomes a simple
* acceleration interpolator.
*/
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);
}
}
(6)AnticipateOvershootInterpolator 開始的時候向後然後向前甩一定值後返回最後的值
/**
* An interpolator where the change starts backward then flings forward and overshoots
* the target value and finally goes back to the final value.
*/
public class AnticipateOvershootInterpolator implements Interpolator {
private final float mTension;
public AnticipateOvershootInterpolator() {
mTension = 2.0f * 1.5f;
}
/**
* @param tension Amount of anticipation/overshoot. When tension equals 0.0f,
* there is no anticipation/overshoot and the interpolator becomes
* a simple acceleration/deceleration interpolator.
*/
public AnticipateOvershootInterpolator(float tension) {
mTension = tension * 1.5f;
}
/**
* @param tension Amount of anticipation/overshoot. When tension equals 0.0f,
* there is no anticipation/overshoot and the interpolator becomes
* a simple acceleration/deceleration interpolator.
* @param extraTension Amount by which to multiply the tension. For instance,
* to get the same overshoot as an OvershootInterpolator with
* a tension of 2.0f, you would use an extraTension of 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);
}
}
(7)OvershootInterpolator
向前甩一定值後再回到原來位置
/**
* An interpolator where the change flings forward and overshoots the last value
* then comes back.
*/
public class OvershootInterpolator implements Interpolator {
private final float mTension;
public OvershootInterpolator() {
mTension = 2.0f;
}
/**
* @param tension Amount of overshoot. When tension equals 0.0f, there is
* no overshoot and the interpolator becomes a simple
* deceleration interpolator.
*/
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;
}
}
(8)BounceInterpolator
動畫結束的時候彈起,有點玻璃球落地時的感覺
/**
* An interpolator where the change bounces at the end.
*/
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;
}
}
(9)CycleInterpolator
動畫循環播放特定的次數,速率改變沿着正弦曲線
/**
* Repeats the animation for a specified number of cycles. The
* rate of change follows a sinusoidal pattern.
*
*/
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;
}
好了,到此爲止,android 動畫-Tween Animation(一)動畫體系簡介,涉及到的核心類、核心接口講解的內容華商一個完美的句號,以上內容純屬理論內容,沒有一個例子,具體的demo在下一節會看到。同時,鄭重聲明,以上內容絕大多數非本人原創,本人本着整理的原則,取精華,去糟粕,重歸納,加上自己的理解,組成這個第一講,主要參考資料如下:
參考資料: