編輯:關於Android編程
做過android動畫的人對Interpolator應該不會陌生,這個類主要是用來控制android動畫的執行速率,一般情況下,如果我們不設置,動畫都不是勻速執行的,系統默認是先加速後減速這樣一種動畫執行速率。
android通過Interpolator類來讓我們自己控制動畫的執行速率,還記得上一篇博客中我們使用屬性動畫實現的旋轉效果嗎?在不設置Interpolator的情況下,這個動畫是先加速後減速,我們現在使用android系統提供的類LinearInterpolator來設置動畫的執行速率,LinearInterpolator可以讓這個動畫勻速執行,我們來看一個案例,我們有兩個TextView重疊放在一起,點擊旋轉按鈕後這兩個TextView同時執行旋轉動畫,不同的是一個設置了LinearInterpolator,而另外一個什麼都沒有設置,代碼如下:
LinearInterpolator ll = new LinearInterpolator();
ObjectAnimator animator = ObjectAnimator.ofFloat(tv, rotation,
0f, 360f);
animator.setInterpolator(ll);
animator.setDuration(5000);
animator.start();
ObjectAnimator animator2 = ObjectAnimator.ofFloat(tv2, rotation,
0f, 360f);
animator2.setDuration(5000);
animator2.start();
效果圖如下:
現在我們可以很清楚的看到這裡的差異,一個TextView先加速後減速,一個一直勻速運動。<喎?/kf/ware/vc/" target="_blank" class="keylink">vcD4NCjxwPtXivs3S/cbwwcvO0rXEusPG5qOsvr++uUxpbmVhckludGVycG9sYXRvctf2wcvKssO0o6y4xLHkwcu2r7uttcTWtNDQy9nCyqGj1eLA787Sw8e+zdKqv7S/tNS0wuvBy6GjPGJyIC8+DQq1sc7Sw8e199PDPGNvZGU+YW5pbWF0b3Iuc2V0SW50ZXJwb2xhdG9yKGxsKTs8L2NvZGU+tcTKsbryo6y199PDtcTKx1ZhbHVlQW5pbWF0b3K3vbeo1tC1xHNldEludGVycG9sYXRvcre9t6ijrNS0wuvI58/Co7o8L3A+DQo8cHJlIGNsYXNzPQ=="brush:java;">
public void setInterpolator(TimeInterpolator value) {
if (value != null) {
mInterpolator = value;
} else {
mInterpolator = new LinearInterpolator();
}
}
我們看到這裡有一個mInterpolator變量,如果我們不執行這個方法,那麼mInterpolator 的默認值是多少呢?
我們找到了這樣兩行代碼:
// The time interpolator to be used if none is set on the animation
private static final TimeInterpolator sDefaultInterpolator =
new AccelerateDecelerateInterpolator();
private TimeInterpolator mInterpolator = sDefaultInterpolator;
這下明朗了,如果我們不設置,那麼系統默認使用AccelerateDecelerateInterpolator,AccelerateDecelerateInterpolator又是什麼呢?繼續看源碼:
public class AccelerateDecelerateInterpolator extends BaseInterpolator
implements NativeInterpolatorFactory {
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;
}
/** @hide */
@Override
public long createNativeInterpolator() {
return NativeInterpolatorFactoryHelper.createAccelerateDecelerateInterpolator();
}
}
這裡的一個核心函數就是getInterpolation,使用了反余弦函數,input傳入的值在0-1之間,因此這裡返回值的變化速率就是先增加後減少,對應的動畫執行速率就是先增加後減速。有興趣的童鞋可以使用MatLab來畫一下這個函數的圖像。而當我們實現了LinearInterpolator之後,情況發生了變化:
public class LinearInterpolator extends BaseInterpolator implements NativeInterpolatorFactory {
public LinearInterpolator() {
}
public LinearInterpolator(Context context, AttributeSet attrs) {
}
public float getInterpolation(float input) {
return input;
}
/** @hide */
@Override
public long createNativeInterpolator() {
return NativeInterpolatorFactoryHelper.createLinearInterpolator();
}
}
這裡干淨利落直接返回了input,沒有經過任何計算。input返回的值是均勻的,因此動畫得以勻速執行。
看到這裡,大家應該就明白了,如果我們想要控制動畫的執行速率,應該重寫getInterpolation方法就能實現。為了證實我們的猜想,我們繼續看源碼。
大部分時候,我們使用的系統提供的各種各樣的**Interpolator,比如上文說的LinearInterpolator,這些類都是繼承自Interpolator,而Interpolator則實現了TimeInterpolator接口,我們來看看一個繼承結構圖:
那麼這個終極大Boss TimeInterpolator究竟是什麼樣子呢?
package android.animation;
/**
* A time interpolator defines the rate of change of an animation. This allows animations
* to have non-linear motion, such as acceleration and deceleration.
*/
public interface TimeInterpolator {
/**
* Maps a value representing the elapsed fraction of an animation to a value that represents
* the interpolated fraction. This interpolated value is then multiplied by the change in
* value of an animation to derive the animated value at the current elapsed animation time.
*
* @param input A value between 0 and 1.0 indicating our current point
* in the animation where 0 represents the start and 1.0 represents
* the end
* @return The interpolation value. This value can be more than 1.0 for
* interpolators which overshoot their targets, or less than 0 for
* interpolators that undershoot their targets.
*/
float getInterpolation(float input);
}
源碼還是很簡單的,只有一個方法,就是getInterpolation,看來沒錯,就是它了,如果我們想要自定義Interpolator,只需要實現TimeInterpolator接口的getInterpolation方法就可以了,getInterpolation方法接收的參數是動畫執行的百分比,這個值是均勻的。
我們來個簡單的案例:
public class TanInterpolator implements TimeInterpolator {
@Override
public float getInterpolation(float t) {
return (float) Math.sin((t / 2) * Math.PI);
}
}
在動畫中使用:
TanInterpolator tl = new TanInterpolator();
ObjectAnimator animator = ObjectAnimator.ofFloat(tv, rotation,
0f, 360f);
animator.setInterpolator(tl);
animator.setDuration(5000);
animator.start();
咦?這是什麼效果?這是一開始速度很大,然後逐漸減小到0的動畫效果.
原因如下:
看下圖,這是sin函數圖象:
x取0-0.5PI,y值則為0-1,這一段曲線的斜率逐漸減小至0,這也是為什麼我們的動畫一開始執行很快,後來速度逐漸變為0.
好了,看完這些,想必大家已經理解了這個類的使用了吧。
一、前言自從去年中微信添加搶紅包的功能,微信的電商之旅算是正式開始正式火爆起來。但是作為Android開發者來說,我們在搶紅包的同時意識到了很多問題,就是手動去搶紅包的速
其實清除緩存是有兩種的,一種是清除手機rom裡面的緩存,一種是清除手機sd卡裡面的緩存,我們今天主要講的就是第一種 ps:這裡來一個知識掃盲,就是手機裡面的rom和r
Android自帶的Email從6.3開始不支持exchange了,用了那麼久,突然不支持了還真是不習慣。市場上也沒有比較好的替代軟件,心想從網上搜一下能不
Visual Studio: C++跨平台的移動解決方案Visual Studio (下載地址) 正在迅速成為一個跨平台的C++IDE。我們的目標是讓Visual Stu