Android常見動畫的使用

Android常見動畫的使用


Android中的動畫有三種,分別是補間動畫、幀動畫、屬性動畫。

1. 補間動畫


通過在兩個關鍵幀之間補充漸變的動畫效果來實現,其優點是可以節省空間。Android目前支持的補間動畫有RotateAnimation(旋轉)、ScaleAnimation(縮放)、AlphaAnimation(透明度)、TranslateAnimation(位移)、AnimationSet(組合)這5種。
實現補間動畫的方式有兩種:1.代碼創建 2.使用xml

第一種:使用代碼創建:
1.1 RotateAnimation(旋轉動畫)

/** 
* 創建旋轉動畫 
*/
private void createRotateAnimation() {
/**     
* 構造方法如下     
*fromDegrees、toDegrees表示開始、結束的角度(0度爲水平方向右側的開始角度),pivotXValue、pivotYValue代表旋轉的中心位置,[0.0f-1.0f],     
*pivotXType、pivotYType表示旋轉的類型(Animation.ABSOLUTE,、Animation.RELATIVE_TO_SELF、Animation.RELATIVE_TO_PARENT)     
*當type爲Animation.ABSOLUTE時,這個個值爲具體的像素值,當type爲Animation.RELATIVE_TO_SELF或Animation.RELATIVE_TO_PARENT,這個個值爲比例值,取值範圍是[0f, 1.0f]     
*public RotateAnimation(float fromDegrees, float toDegrees, int pivotXType, float pivotXValue,int pivotYType, float pivotYValue) {     }    
*/    
//初始化RotateAnimation
RotateAnimation animation = new RotateAnimation(0, 360, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);    
//動畫執行時間
animation.setDuration(2000);    
//動畫重複次數-1表示不停重複    
//animation.setRepeatCount(-1);    
//給控件設置動畫    
mTv.startAnimation(animation);
}

1.2 ScaleAnimation(縮放動畫)

/** 
* 創建縮放動畫 
*/
private void createScaleAnimation() {    
/**     
* 構造方法如下     
* fromX、toX 開始結束的X軸縮放比率[0.0f-1.0f],fromY、toYtoY開始結束的Y軸縮放比率[0.0f-1.0f],pivotXValue、pivotYValue代表旋轉的中心位置,[0.0f-1.0f],     
* pivotXType、pivotYType表示旋轉的類型(Animation.ABSOLUTE,、Animation.RELATIVE_TO_SELF、Animation.RELATIVE_TO_PARENT)     
* 當type爲Animation.ABSOLUTE時,這個個值爲具體的像素值,當type爲Animation.RELATIVE_TO_SELF或Animation.RELATIVE_TO_PARENT,這個個值爲比例值,取值範圍是[0f, 1.0f]     
*  public ScaleAnimation(float fromX, float toX, float fromY, float toY,int pivotXType, float pivotXValue, int pivotYType, float pivotYValue) {}     
*/    
//初始化ScaleAnimation    
ScaleAnimation animation = new ScaleAnimation(1f, 0.5f, 1f, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);    
//動畫執行時間    
animation.setDuration(2000);    
//動畫重複次數-1表示不停重複    
//animation.setRepeatCount(-1);    
//給控件設置動畫    
mTv.startAnimation(animation);
}

1.3 AlphaAnimation(透明度)

/** 
* 創建透明度漸變動畫 
*/
private void createAlphaAnimation() {    
/***     
* 構造方法如下     
* fromAlpha、toAlpha表示透明度的起始值和結束值,0.0f表示全透明,1.0f表示不透明。     
* public AlphaAnimation(float fromAlpha, float toAlpha) {}     
*/    
//初始化AlphaAnimation    
AlphaAnimation animation = new AlphaAnimation(1.0f, 0.0f);    
//動畫執行時間    animation.setDuration(2000);    
//動畫重複次數-1表示不停重複    
//animation.setRepeatCount(-1);    
//給控件設置動畫    
mTv.startAnimation(animation);
}

1.4 TranslateAnimation(位移)

 /**     
* 創建位移動畫     
*/    
private void createTranslateAnimation() {        
/**         
* 構造方法如下         
* fromXType、toXType、fromYType、toYType(Animation.ABSOLUTE,、Animation.RELATIVE_TO_SELF、Animation.RELATIVE_TO_PARENT)         
* 當type爲Animation.ABSOLUTE時,這個個值爲具體的像素值,當type爲Animation.RELATIVE_TO_SELF或Animation.RELATIVE_TO_PARENT,這個個值爲比例值,取值範圍是[0f, 1.0f]         
*public TranslateAnimation(int fromXType, float fromXValue, int toXType, float toXValue,int fromYType, float fromYValue, int toYType, float toYValue) {}              
*/        
TranslateAnimation animation = new TranslateAnimation(Animation.RELATIVE_TO_SELF, 0f,                
Animation.RELATIVE_TO_SELF, 0f, Animation.RELATIVE_TO_SELF, 0f, Animation.ABSOLUTE, 100);        
animation.setDuration(2000);        
//動畫重複次數-1表示不停重複        
//animation.setRepeatCount(-1);
//動畫結束後View停留在結束位置
//animation.setFillAfter(true);        
mTv.startAnimation(animation);    }

1.5 AnimationSet(組合)

/** * 創建組合動畫 
*/
private void createAnimationSet(){    
AnimationSet animationSet = new AnimationSet(true);    
AlphaAnimation alphaAnimation = new AlphaAnimation(1.0f, 0.0f);    
ScaleAnimation scaleAnimation = new ScaleAnimation(1f, 0.5f, 1f, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);    
RotateAnimation rotateAnimation = new RotateAnimation(0, 360, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);    
TranslateAnimation translateAnimation = new TranslateAnimation(Animation.RELATIVE_TO_SELF, 0f, Animation.RELATIVE_TO_SELF, 0f, Animation.RELATIVE_TO_SELF, 0f, Animation.ABSOLUTE, 100);    animationSet.addAnimation(alphaAnimation);    
animationSet.addAnimation(scaleAnimation);    
animationSet.addAnimation(rotateAnimation);    
animationSet.addAnimation(translateAnimation);   
animationSet.setDuration(2000);    
animationSet.setRepeatCount(-1);    
mTv.startAnimation(animationSet);}

AnimationSet animationSet = new AnimationSet(true); true表示這個組合動畫公用一個插值器,插值器的概念和使用方法,我會在文章的末尾進行說明。

第二種:使用xml創建,在res下創建anim文件夾,如圖:


alpha_demo.xml:

<?xml version="1.0" encoding="utf-8"?>
<alpha xmlns:android="http://schemas.android.com/apk/res/android"       
android:fromAlpha="1.0"       
android:toAlpha="0.0"       
android:duration="2000">
</alpha>
</rotate>

rotate_demo.xml:

<?xml version="1.0" encoding="utf-8"?>
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="2000"        
android:fromDegrees="0"        
android:pivotX="50%"        
android:pivotY="50%"        
android:toDegrees="360">
</rotate>

scale_demo.xml:

<?xml version="1.0" encoding="utf-8"?>
<scale xmlns:android="http://schemas.android.com/apk/res/android"       
android:fromXScale="1.0"       
android:toXScale="0.5"       
android:fromYScale="1"       
android:toYScale="0.5"       
android:pivotX="50%"       
android:pivotY="50%"       
android:duration="2000">
</scale>

translate_demo.xml:

<?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"           
android:fromXDelta="0"           
android:toXDelta="0"           
android:fromYDelta="0"           
android:toYDelta="100"           
android:duration="2000">
</translate>

set_demo.xml:

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"     
android:duration="2000"    >    
<scale        
android:fromXScale="1"        
android:fromYScale="1"        
android:pivotX="50%"        
android:pivotY="50%"        
android:toXScale="0.5"        
android:toYScale="0.5" />    
<rotate        
android:fromDegrees="0"        
android:pivotX="50%"        
android:pivotY="50%"        
android:toDegrees="360"/>    
<translate        
android:fromXDelta="0"        
android:fromYDelta="0"        
android:toXDelta="0"        
android:toYDelta="100"/>    
<alpha        
android:fromAlpha="1.0"        
android:toAlpha="0.1"/>
</set>

效果圖:


補間動畫效果圖

2.幀動畫

幀動畫幀動畫顧名思義,一幀一幀播放的動畫就是幀動畫。 幀動畫和我們小時候看的動畫片的原理是一樣的,在相同區域快速切換圖片給人們呈現一種視覺的假象感覺像是在播放動畫,其實不過是多張圖片在一幀一幀的切換罷了。切記,圖片不易過多過大,不然容易產生OOM。

先在drawble下新建一個xml:


Paste_Image.png

frame_animation.xml:

<?xml version="1.0" encoding="utf-8"?>
<animation-list xmlns:android="http://schemas.android.com/apk/res/android"                
android:oneshot="false">    
//oneshot屬性表示是否循環播放,值爲true則只播放一次。    
<item        android:drawable="@mipmap/animation1"        android:duration="200"/>   
<item        android:drawable="@mipmap/animation2"        android:duration="200"/>   
<item        android:drawable="@mipmap/animation3"        android:duration="200"/>    
<item        android:drawable="@mipmap/animation4"        android:duration="200"/>    
<item        android:drawable="@mipmap/animation5"        android:duration="200"/>   
<item        android:drawable="@mipmap/animation6"        android:duration="200"/>    
<item        android:drawable="@mipmap/animation7"        android:duration="200"/>    
<item        android:drawable="@mipmap/animation8"        android:duration="200"/>
</animation-list>

java代碼:

/** 
* 幀動畫 
*/
public class FrameAnimation extends AppCompatActivity {    
@Bind(R.id.img)    
ImageView mImg;    
@Bind(R.id.btn1)    
Button mBtn1;    
@Bind(R.id.btn2)    
Button mBtn2;    
AnimationDrawable animationDrawable;    
@Override    
protected void onCreate(Bundle savedInstanceState) {        
super.onCreate(savedInstanceState);        
setContentView(R.layout.activity_frame_animation);        
ButterKnife.bind(this);        
mImg.setImageResource(R.drawable.frame_animation);        
animationDrawable = (AnimationDrawable) mImg.getDrawable();    
}    
@OnClick({R.id.btn1, R.id.btn2})    
public void onClick(View view) {        
switch (view.getId()) {            
case R.id.btn1:                
animationDrawable.start();                
break;            
case R.id.btn2:                
animationDrawable.stop();                
break;        
}    
}}

效果如下:


幀動畫效果圖

3.屬性動畫

在Android3.0之後才引進的,屬性動畫改變的是對象的實際屬性,如ImageView的縮放,ImageView的位置與大小屬性值都改變了。屬性動畫不止可以應用於View,還可以應用於任何對象。屬性動畫只是表示一個值在一段時間內的改變,當值改變時要做什麼事情完全是你自己決定的。ValueAnimator和ObjectAnimator是屬性動畫的兩個核心類。

3.1 ValueAnimator:對一個範圍內的值進行一個平滑的動畫過渡效果
下面的動畫是在2s內實現從100到50的一個動畫,然後每次更新獲取到值後進行你要的操作,我是這麼做的:

private void createValueAnimator() {
//初始化ValueAnimator     
ValueAnimator valueAnimator = ValueAnimator.ofInt(100, 80);    
//監聽動畫   
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {        
@Override        
public void onAnimationUpdate(ValueAnimator animation) {            
int value = (int) animation.getAnimatedValue();//當前的值            
mImg.getLayoutParams().width = value;   
mImg1.getLayoutParams().height = value;         
mImg.requestLayout();        
}   
 });    
valueAnimator.setDuration(2000);//動畫時長    
valueAnimator.start();//啓動動畫}

除了ValueAnimator.ofInt(),常用的還有ValueAnimator.ofFloat()、ValueAnimator.ofArgb(),ValueAnimator.ofFloat()是實現浮點數的平滑過渡,用法跟ValueAnimator.ofInt()差不多是一樣的,那我們看看ValueAnimator.ofArgb(),實現顏色值的過渡,舉個例子:

private void vreateValueAnimatorArgb(){    
//ValueAnimator.ofArgb()方法是在API Level 21中才加入的    
if(Build.VERSION.SDK_INT >= 21){        
ValueAnimator valueAnimator = ValueAnimator.ofArgb(R.color.red,R.color.blue);
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {          
@Override            
public void onAnimationUpdate(ValueAnimator animation) {                
int color = (int) animation.getAnimatedValue();                
mImg.setBackgroundResource(color);                
mImg.requestLayout();                
Log.d("AAA",color+"");            
}        
});        
valueAnimator.setDuration(2000);//動畫時長        
valueAnimator.start();//啓動動畫    
}}

3.2 ObjectAnimator 對任意對象的屬性進行動畫操作,那麼,ObjectAnimator肯定是可以實現補間動畫的效果咯,注意,要設置的對象的屬性,必須要有set方法,不然不起作用的。
舉一個例子,我們設置一個對象的縮放動畫:

ObjectAnimator animator = ObjectAnimator.ofFloat(mImg, "scaleX", 1f, 2f);
animator.setDuration(2000);
animator.start();

這裏我們設置對象的屬性爲scaleX,表示這個動畫執行的時候,會在水平方向將mImg(mImg是個ImageView)的寬度拉伸兩倍,由於mImg這個對象沒有setScale()這個方法,所以這裏就不能設置屬性爲"scale",這樣是沒有效果的。同樣,我們也可以設備對象的旋轉、透明度、平移的動畫,只需要修改對象的屬性就可以了,這裏就不再舉例。

3.3 跟補間動畫類似,屬性動畫也可以將多個動畫組合在一起執行,如果多個動畫同時執行,則調用animatorSet.playTogether(),如果動畫執行的先後順序不一樣,則通過animatorSet.play()獲得一個AnimatorSet.Builder對象,這個對象有四個方法:
after(Animator anim) 將現有動畫插入到傳入的動畫之後執行
after(long delay) 將現有動畫延遲指定毫秒後執行
before(Animator anim) 將現有動畫插入到傳入的動畫之前執行
with(Animator anim) 將現有動畫和傳入的動畫同時執行

AnimatorSet animatorSet = new AnimatorSet();
ObjectAnimator alpha = ObjectAnimator.ofFloat(view, "alpha", 1f, 0f, 1f);
ObjectAnimator rotation = ObjectAnimator.ofFloat(view, "rotation", 0f, 360f);
ObjectAnimator translation = ObjectAnimator.ofFloat(view, "translationX", 400f, 0f);
ObjectAnimator scale = ObjectAnimator.ofFloat(view, "scaleX", 1f, 2f, 1f);
animatorSet.playTogether(alpha,rotation,translation,scale);//動畫同時執行
//如果不同時執行,則如下,根據自己的需求可以自己調整
//animatorSet.play(alpha).with(translation).after(rotation).before(scale);
animatorSet.setDuration(5000);animatorSet.start();

3.4 跟補間動畫一樣,屬性動畫也可以使用xml的方式,在res下創建animator文件夾,如下:



可以使用的標籤有<animator>、<objectAnimator> 和<set>,分別表示ValueAnimator、ObjectAnimator和AnimatorSet。比如上面我們用ObjectAnimator實現的旋轉動畫,用xml來寫的話就是醬紫的:

<?xml version="1.0" encoding="utf-8"?>
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android" 
android:duration="2000" 
android:propertyName="rotation" 
android:valueFrom="0" 
android:valueTo="360" 
android:valueType="floatType" />

<animator>和<set>標籤就不舉例啦,使用方法都是大同小異,大家多寫幾遍就會了,最後我們看一下在代碼中如何使用這個xml:

Animator animator = AnimatorInflater.loadAnimator(context, R.animator.anim_test); //anim_test就是我們寫的xml文件
animator.setTarget(view); //view表示我們要設置動畫的對象
animator.start();

3.5屬性動畫也可以監聽動畫執行的狀態,有兩種方式,可以根據自己的需要選擇,代碼如下:
第一種:

animator.addListener(new Animator.AnimatorListener() { 
@Override 
public void onAnimationStart(Animator animation) { } 
@Override 
public void onAnimationEnd(Animator animation) { } 
@Override 
public void onAnimationCancel(Animator animation) { } 
@Override 
public void onAnimationRepeat(Animator animation) { } 
});

第二種

animator.addListener(new AnimatorListenerAdapter() { 
@Override 
public void onAnimationStart(Animator animation) { 
super.onAnimationStart(animation); 
} 
@Override 
public void onAnimationEnd(Animator animation) { 
super.onAnimationEnd(animation); 
} 
});

簡單看一下效果(有點醜,哈哈!!!):


屬性動畫效果圖

3.6 最後補充一下插值器的概念,所謂的插值器,就是我們執行的動畫速度的改變規律,常用的插值器有以下幾LinearInterpolator(勻速)、AccelerateInterpolator(加速)、AccelerateDecelerateInterpolator(先加速再減速)、BounceInterpolator(反彈數次後停止)、DecelerateInterpolator(減速),我們在代碼或者xml中都可以使用插值器。
java代碼中使用插值器:

RotateAnimation animation = new RotateAnimation(0, 360, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
animation.setDuration(2000);
animation.setInterpolator(new LinearInterpolator());//設置一個勻速的插值器
mTv.startAnimation(animation);

xml中使用插值器:

<?xml version="1.0" encoding="utf-8"?>
<rotate xmlns:android="http://schemas.android.com/apk/res/android"        
android:duration="2000"        
android:fromDegrees="0"        
android:pivotX="50%"        
android:pivotY="50%"        
android:interpolator="@android:anim/linear_interpolator"        
android:toDegrees="360">
</rotate>

最後看一下這5中插值器的效果,就拿上面的補間動畫修改一下好了,效果如下:


加了插值器的效果圖

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章