1.補(bǔ)間動(dòng)畫
無需逐一定義每一幀洋只,只要定義開始辆沦、結(jié)束的幀,和指定動(dòng)畫持續(xù)時(shí)間识虚。
補(bǔ)間動(dòng)畫有4種(均為Animation抽象類子類):
AlphaAnimation(透明度肢扯,0~1)
ScaleAnimation(大小縮放,X担锤、Y軸縮放蔚晨,還包括縮放中心pivotX、pivotY)
TranslationAnimation(位移肛循,X铭腕、Y軸位移)
RotateAnimation(旋轉(zhuǎn),包括縮放中心pivotX多糠、pivotY)
public void move(View view){
//定義一個(gè)位移補(bǔ)間動(dòng)畫累舷,X軸從0變化到100,Y軸不變
TranslateAnimation animation = new TranslateAnimation(0, 200, 0, 0);
//設(shè)置動(dòng)畫持續(xù)時(shí)間
animation.setDuration(1000);
//設(shè)置動(dòng)畫結(jié)束后效果保留
animation.setFillAfter(true);
//控制動(dòng)畫先慢后快
animation.setInterpolator(new AccelerateInterpolator());
//找到對象夹孔,開啟動(dòng)畫
mImageView = (ImageView) findViewById(R.id.imageView1);
mImageView.startAnimation(animation);
指定3個(gè)信息后被盈,動(dòng)畫是勻速的,效果同逐幀動(dòng)畫搭伤。
上例中還有一個(gè)屬性只怎,可以控制速度,即為Interpolator(插值)怜俐,有以下幾種(Interpolator的實(shí)現(xiàn)類):
LinearInterpolator(勻速)
AccelerateInterpolator(先慢后快)
AccelerateDecelerateInterpolator(先慢中快后慢)
DecelerateInterpolator(先快后慢)
CycleInterpolator(循環(huán)播放身堡,速度為正弦曲線)
AnticipateInterpolator(先回撤,再勻速向前)
OvershootInterpolator(超過拍鲤,拉回)
BounceInterpolator(回彈)
不僅可以在代碼中創(chuàng)建Animation對象盾沫,很多情況下裁赠,是采用動(dòng)畫資源文件來定義補(bǔ)間動(dòng)畫。資源目錄:res/anim/anim.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<!-- 定義縮放動(dòng)畫 -->
<scale android:fromXScale="1.o"
android:fromYScale="1.0"
android:toXScale="0.01"
android:toYScale="0.01"
android:pivotX="50%"
android:pivotY="50%"
android:fillAfter="true"
android:duration="1000"/>
<!-- 定義透明度動(dòng)畫 -->
<alpha android:fromAlpha="1"
android:toAlpha="0.05"
android:duration="3000"/>
<!-- 定義旋轉(zhuǎn)動(dòng)畫 -->
<rotate android:fromDegrees="0"
android:toDegrees="1800"
android:pivotX="50%"
android:pivotY="50%"
android:duration="2000"/>
</set>
然后在代碼中使用AnimationUtils工具類加載動(dòng)畫資源赴精,返回一個(gè)Animation對象
Animation animation = AnimationUtils.loadAnimation(this, R.anim.anim);
2.屬性動(dòng)畫
繼承關(guān)系:
Animator(屬性動(dòng)畫的基類)→ValueAnimator→ObjectAnimator
如何使用:
1.調(diào)用ObjectAnimator的靜態(tài)工廠方法創(chuàng)建動(dòng)畫(ofInt佩捞、ofFloat、ofObject)
2.調(diào)用SetXxx()設(shè)置動(dòng)畫持續(xù)時(shí)間、插值方式转晰、重復(fù)次數(shù)等徐紧。
3.監(jiān)聽事件
4.調(diào)用Animator對象的start()方法啟動(dòng)動(dòng)畫
//標(biāo)準(zhǔn)示范,單個(gè)動(dòng)畫屬性(ObjectAnimator)執(zhí)行
public void move1(View view){
//直接調(diào)用ObjectAnimator的工廠方法(靜態(tài)方法)帘营,可以創(chuàng)建ObjectAnimator實(shí)例
//前2個(gè)參數(shù)分別要指定:操作的具體的對象、操作的對象的屬性逐哈。本例中芬迄,具體對象為ImageView,屬性為X軸位移
//第3個(gè)參數(shù)昂秃,是操作的對象的屬性禀梳,其動(dòng)畫變化的范圍的。本例中肠骆,X軸位移:0f~200f
ObjectAnimator.ofFloat(mImageView, "translationX", 0f,200f)
.setDuration(2000)
.start();
}
//同一個(gè)對象設(shè)置多個(gè)屬性動(dòng)畫算途,會(huì)同時(shí)執(zhí)行∈赐龋可見嘴瓤,屬性動(dòng)畫實(shí)例調(diào)用start方法后,是一個(gè)異步的過程
public void move2(View view){
ObjectAnimator.ofFloat(mImageView, "translationX", 0f,200f).setDuration(2000).start();
ObjectAnimator.ofFloat(mImageView, "translationY", 0f,200f).setDuration(2000).start();
ObjectAnimator.ofFloat(mImageView, "rotation", 0f,360f).setDuration(2000).start();
}
//(多個(gè)動(dòng)畫同時(shí)時(shí)推薦)莉钙,使用PropertyValuesHolder廓脆,先將多個(gè)屬性動(dòng)畫hold住,再一起開啟動(dòng)畫磁玉,可以實(shí)現(xiàn)同樣的效果狞贱。如此做法對動(dòng)畫進(jìn)行了優(yōu)化,使用多個(gè)屬性的時(shí)候蜀涨,更加節(jié)省系統(tǒng)資源瞎嬉。
public void move3(View view){
PropertyValuesHolder p1 = PropertyValuesHolder.ofFloat("translationX", 0f,200f);
PropertyValuesHolder p2 = PropertyValuesHolder.ofFloat("translationY", 0f,200f);
PropertyValuesHolder p3 = PropertyValuesHolder.ofFloat("rotation", 0f,360f);
ObjectAnimator.ofPropertyValuesHolder(mImageView, p1,p2,p3).setDuration(2000).start();
}
//(多個(gè)動(dòng)畫需求不同時(shí)時(shí)推薦),利用AnimatorSet厚柳,組合多個(gè)Animation氧枣,可以對多個(gè)動(dòng)畫屬性進(jìn)行順序控制
//同時(shí)執(zhí)行:set.playTogether(animator1,animator2,animator3)
//順序執(zhí)行:set.playSequentially(animator1,animator2,animator3)
//分布執(zhí)行:play().with(); play().after();
public void move4(View view){
ObjectAnimator animator1 = ObjectAnimator.ofFloat(mImageView, "translationX", 0f,200f);
ObjectAnimator animator2 = ObjectAnimator.ofFloat(mImageView, "translationY", 0f,200f);
ObjectAnimator animator3 = ObjectAnimator.ofFloat(mImageView, "rotation", 0f,360f);
AnimatorSet set = new AnimatorSet();
set.play(animator1).with(animator2);
set.play(animator3).after(animator1);
set.setDuration(1000).start();
}
利用addListener(listener)給Animator對象設(shè)置監(jiān)聽器。監(jiān)聽事件有很多種别垮,如果參數(shù)直接給一個(gè)new AnimatorListener
便监,系統(tǒng)會(huì)直接override全部的監(jiān)聽事件讓我們覆寫onAnimationStart
onAnimationRepeat
onAnimationEnd
onAnimationCancel
。如果只想監(jiān)聽個(gè)別事件,參數(shù)寫成new AnimatorListenerAdapter
烧董,然后Alt+Shift+S毁靶,選擇需要覆寫的實(shí)現(xiàn)方法即可。
//對動(dòng)畫設(shè)置監(jiān)聽事件
public void move5(View view){
ObjectAnimator animator = ObjectAnimator.ofFloat(view, "alpha", 0f,1.0f);
animator.setDuration(1000).start();
animator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
mImageView.setVisibility(View.VISIBLE);
ObjectAnimator.ofFloat(mImageView, "alpha", 0f,1.0f).setDuration(1000).start();
}
});
}
3.屬性動(dòng)畫實(shí)例(點(diǎn)擊父菜單圖標(biāo)逊移,彈出多個(gè)子菜單圖標(biāo))
public class AnimatorPath extends Activity implements OnClickListener{
private int [] res = {R.id.imageView0,R.id.imageView1,R.id.imageView2,
R.id.imageView3,R.id.imageView4,R.id.imageView5,
R.id.imageView6,R.id.imageView7,};
private List<ImageView> imageViewList = new ArrayList<ImageView>();
private boolean flag = true;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.animator_path);
//用集合的方式遍歷ImageView预吆,并添加進(jìn)集合
for(int i =0 ; i< res.length; i++){
ImageView imageView =(ImageView) findViewById(res[i]);
imageView.setOnClickListener(this);
imageViewList.add(imageView);
}
}
//給幀布局文件中ImageView添加點(diǎn)擊事件(使用Animator動(dòng)畫,動(dòng)畫后的ImageView也可以設(shè)置點(diǎn)擊監(jiān)聽)
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.imageView0:
if(flag){
startAnim();
flag = false;
}else{
endAnim();
flag = true;
}
break;
default:
break;
}
}
//設(shè)置每個(gè)小球向前不同的距離胳泉,此處需求幾個(gè)動(dòng)畫同時(shí)執(zhí)行拐叉,就使用了最簡單的實(shí)現(xiàn)方式
private void startAnim() {
for(int i =0; i< res.length; i++){
ObjectAnimator animator = ObjectAnimator.ofFloat(imageViewList.get(i), "translationY",0f, 100f*i);
animator.setDuration(500).setStartDelay(150*i);
animator.setInterpolator(new BounceInterpolator());
animator.start();
}
}
private void endAnim() {
for(int i = 0; i<res.length; i++){
ObjectAnimator animator = ObjectAnimator.ofFloat(imageViewList.get(i), "translationY", 100f*i,0f);
animator.setDuration(250).setStartDelay(150*i);
animator.start();
}
}
}