屬性動畫可直接改變View的屬性值扩所,屬性動畫幾乎可以對任意對象執(zhí)行動畫祖屏,而不局限在View對象執(zhí)行動畫。
基本屬性
動畫持續(xù)時間:默認值是300ms袁勺,通過android:duration指定
動畫插值方式:android:interpolator
動畫重復次數(shù):動畫重復播放次數(shù)期丰,android:repeatCount
動畫重復模式:在一次動畫播放結(jié)束后,重復下次動畫時街立,是從開始幀再次播放到結(jié)束幀埠通,還是從結(jié)束幀反方向播放到開始幀。android:repeatMode
幀刷新頻率:指定間隔多長時間播放一幀梁剔,默認值是10毫秒
動畫集合
Eavluator
是用來控制屬性動畫如何計算屬性值的舞蔽。
它的接口是TypeEvalutor,其中定義了evaluate方法,供不同的子類實現(xiàn)。
public interface TypeEvaluator<T> {
public T evaluate(float fraction, T startValue, T endValue);
}
**輸入初始值和結(jié)束值及一個進度比灸拍,計算每個進度對應(yīng)的值鸡岗。
常見的實現(xiàn)類有
ArgbEvaluator,IntEvaluator,FloatEvaluator
ValueAnimator
屬性動畫最重要的一個類声登,繼承自Animator,它定義了屬性動畫大部分的核心功能悯嗓,包括計算各幀的屬性值,處理更新時間铅祸,按照屬性值的類型控制計算規(guī)則等合武。
一個完整的屬性動畫由兩部分組成:
1.計算動畫各幀的相關(guān)屬性值稼跳。
2.將這些屬性值設(shè)置給指定對象。
ValueAnimator為開發(fā)者完成了第一部分的功能汤善,第二部分功能由開發(fā)者自行設(shè)置萎津。
ValueAnimator的構(gòu)造函數(shù)是空實現(xiàn),一般由使用靜態(tài)工廠方法來進行實例化锉屈。
public static ValueAnimator ofInt(int... values) {
ValueAnimator anim = new ValueAnimator();
anim.setIntValues(values);
return anim;
}
public static ValueAnimator ofArgb(int... values) {
ValueAnimator anim = new ValueAnimator();
anim.setIntValues(values);
anim.setEvaluator(ArgbEvaluator.getInstance());
return anim;
}
public static ValueAnimator ofFloat(float... values) {
ValueAnimator anim = new ValueAnimator();
anim.setFloatValues(values);
return anim;
}
public static ValueAnimator ofPropertyValuesHolder(PropertyValuesHolder... values) {
ValueAnimator anim = new ValueAnimator();
anim.setValues(values);
return anim;
}
public static ValueAnimator ofObject(TypeEvaluator evaluator, Object... values) {
ValueAnimator anim = new ValueAnimator();
anim.setObjectValues(values);
anim.setEvaluator(evaluator);
return anim;
}
獲取實例颈渊,設(shè)置動畫持續(xù)時間俊嗽,差值方式,重復次數(shù)等屬性值绍豁,啟動動畫竹揍。為ValueAnimator 注冊addUpdateListener監(jiān)聽器,并在這個方法中計算出來的屬性設(shè)置給指定對象芬位。
int statusBarColor = this.getWindow().getStatusBarColor();
ValueAnimator valueAnimator = ValueAnimator.ofObject(new ArgbEvaluator(), statusBarColor, color);
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
Test.this.getWindow().setStatusBarColor((Integer) animation.getAnimatedValue());
}
});
valueAnimator.setDuration(300).setStartDelay(0);
valueAnimator.start();
ValueAnimator改變高度案例
隱藏顯示—
1通過更改height逐漸的變?yōu)?
2更改整個view的paddingyop—改成父值
為了整體控制動畫—在外面再包一層布局
開始默認隱藏三個布局
//一開始應(yīng)該讓下面的三個布局隱藏昧碉,將其height設(shè)置為0--通過params
//為了獲取最初的高度--設(shè)置一個布局監(jiān)聽器--局對可以取到寬高
llSafeAnim.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
llSafeAnim.getViewTreeObserver().removeGlobalOnLayoutListener(this);
//記錄最初的高度--一遍之后變回來
height = llSafeAnim.getHeight();
//將當前的高度設(shè)置為0--隱藏---這里使用.getLayoutParams因為在布局里面寫
//線性布局是繼承自viewgroup
ViewGroup.LayoutParams params = llSafeAnim.getLayoutParams();
params.height = 0;
llSafeAnim.setLayoutParams(params);
}
});
點擊切換動畫
int height;//最初的高度
//定義變量boolean--完成切換--默認為不打開
boolean isOpen = false;
//設(shè)置整個模塊條目的點擊事件
@OnClick(R.id.safe_module)
public void onViewClicked() {
//ValueAnimator控制值在指定范圍內(nèi)改變的動畫對象, 注意:它只是負責讓值進行改變,
//本身不會有任何的動畫效果
ValueAnimator animator = null;
if (isOpen) {
//ValueAnimator使用--需要關(guān)閉
animator = ValueAnimator.ofInt(height, 0);
} else {
//ValueAnimator使用--需要打開
animator = ValueAnimator.ofInt(0, height);
}
//設(shè)置時間
animator.setDuration(600).start();
//置為反值
isOpen = !isOpen;
}
監(jiān)聽值的變化過程—將值設(shè)置給height實現(xiàn)動畫—執(zhí)行之前進行監(jiān)聽
//監(jiān)聽值的變化過程
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
//獲取動畫的值--默認是object類型--強轉(zhuǎn)
int animatedValue = (int) animation.getAnimatedValue();
//我們只需要將值設(shè)置給height
ViewGroup.LayoutParams params = llSafeAnim.getLayoutParams();
params.height = animatedValue;
llSafeAnim.setLayoutParams(params);
}
});
添加監(jiān)聽動畫結(jié)束語開始
//監(jiān)聽動畫
animator.addListener(new MyAnimatorListener());
//設(shè)置時間
animator.setDuration(600).start();
//置為反值
isOpen = !isOpen;
class MyAnimatorListener extends AnimatorListenerAdapter {
//當動畫結(jié)束
@Override
public void onAnimationEnd(Animator animation) {
isAnimRunning = false;
}
///當動畫開始
@Override
public void onAnimationStart(Animator animation) {
isAnimRunning = true;
}
}
ObjectAnimator
ObjectAnimator是ValueAnimator 的子類,封裝實現(xiàn)了屬性值設(shè)置給指定對象的功能.
只有在ObjectAnimator實現(xiàn)不了的場景下才考慮使用ValueAnimator 箭养。
ObjectAnimator最大的不同是在構(gòu)造實例中需要指定作用的具體對象和對象的屬性名,而且一般不需要注冊addUpdateListener監(jiān)聽器喝检。
傳統(tǒng)animator--Objectanimator.ofXXX
透明效果-alpha
//獲取ObjectAnimator對象
ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(iv, "alpha",
1.0f, 0.5f, 0.0f, 0.2f, 0.7f, 1.0f);
// 參數(shù)1:target 目標:產(chǎn)生的動畫效果 誰來執(zhí)行
// 參數(shù)2:屬性名字 字符串類型--針對(參數(shù)1)控件來說 --alpha透明--可以通過
// 控件.set看一下都有哪些方法--也就是有什么參數(shù)
// 參數(shù)3:可變參數(shù)--數(shù)組
//設(shè)置動畫執(zhí)行時間
objectAnimator.setDuration(2000);
//開始執(zhí)行動畫
objectAnimator.start();
旋轉(zhuǎn)效果
//獲取ObjectAnimator對象
ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(iv, "rotationX", 0, 90, 180, 360);
// 參數(shù)1:target 目標:產(chǎn)生的動畫效果 誰來執(zhí)行
// 參數(shù)2:屬性名字 字符串類型--針對(參數(shù)1)控件來說 --rotationX按照x軸移旋轉(zhuǎn)--可以通過
// 控件.set看一下都有哪些方法--也就是有什么參數(shù)
// 參數(shù)3:可變參數(shù)--數(shù)組
//設(shè)置動畫執(zhí)行時間
objectAnimator.setDuration(2000);
//開始執(zhí)行動畫
objectAnimator.start();
縮放動畫
//獲取ObjectAnimator對象
ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(iv, "scaleX",
1.0f, 2.0f, 3.0f);
// 參數(shù)1:target 目標:產(chǎn)生的動畫效果 誰來執(zhí)行
// 參數(shù)2:屬性名字 字符串類型--針對(參數(shù)1)控件來說 --scaleX按照x軸縮放--可以通過
// 控件.set看一下都有哪些方法--也就是有什么參數(shù)
// 參數(shù)3:可變參數(shù)--數(shù)組
//設(shè)置動畫執(zhí)行時間
objectAnimator.setDuration(2000);
//開始執(zhí)行動畫
objectAnimator.start();
位移動畫
//獲取ObjectAnimator對象
ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(iv,
"translationX", 20, 30, 40, 100, -150);
// 參數(shù)1:target 目標:產(chǎn)生的動畫效果 誰來執(zhí)行
// 參數(shù)2:屬性名字 字符串類型--針對(參數(shù)1)控件來說 --translationX按照x軸移動--可以通過
// 控件.set看一下都有哪些方法--也就是有什么參數(shù)
// 參數(shù)3:可變參數(shù)--數(shù)組
//設(shè)置動畫執(zhí)行時間
objectAnimator.setDuration(2000);
//開始執(zhí)行動畫
objectAnimator.start();
動畫合集
AnimatorSet 是Animator的子類,用來組合多個animator愿题。
AnimatorSet set = new AnimatorSet();
ObjectAnimator aa = ObjectAnimator.ofFloat(iv, "alpha", 1.0f, 0.5f,
0.0f, 0.2f, 0.7f, 1.0f);
ObjectAnimator ra = ObjectAnimator.ofFloat(iv, "rotationX", 0, 90, 180,
360);
ObjectAnimator sa = ObjectAnimator.ofFloat(iv, "scaleX", 1.0f, 2.0f,
3.0f);
ObjectAnimator ta = ObjectAnimator.ofFloat(iv, "translationX", 20, 30,
40, 100, -150);
//四個動畫一起執(zhí)行
// set.playTogether(aa,ra,sa,ta);
//四個動畫順序執(zhí)行
set.playSequentially(aa, ra, sa, ta);
//設(shè)置iv來執(zhí)行動畫
set.setTarget(iv);
//設(shè)置執(zhí)行時間
set.setDuration(2000);
//開始執(zhí)行
set.start();
標準寫法
//屬性動畫的標準寫法:
//ViewCompat.animate(tv1).translationZBy(100).setDuration(3000).start();
//帶by每次都會執(zhí)行--不帶by只執(zhí)行一次
ViewCompat.animate(tv1)
.translationZBy(100)
//.rotationBy(720)
//旋轉(zhuǎn)
.rotationYBy(720)//繞著y軸旋轉(zhuǎn)
//縮放
.scaleXBy(0.3f)
.scaleYBy(0.3f)//每次放大0.3
//移動
.translationYBy(20)
//.alphaBy()透明
//靈動的感覺
//OvershootInterpolator超過后再回來
//.setInterpolator(new OvershootInterpolator())
//BounceInterpolator--彈簧的感覺
.setInterpolator(new BounceInterpolator())
.setDuration(3000).start();