在app中增加一些動畫效果能使我們的app更加絢麗,本文主要總結android中的Animation
Android中的Animation可以分為三種,View Animation,Drawable Animation ,Property Animation,其中第一種比較簡單,只能實現一些簡單的平移,縮放,旋轉,透明度漸變的基本動畫效果,第二種可以實現一種逐幀動畫效果,而第三種屬性動畫比較復雜,Android 3.0之后出現,view動畫能實現的它都能實現,除此之外還能實現很多其他的動畫效果。
1.View動畫,它的實現方式有兩種,XML方式和javacode方式
XML方式:
- 新建項目,在res目錄中新建anim文件夾
- 在anim目錄中新建動畫代碼
- 載入XML動畫效果
直接上代碼
透明度漸變動畫
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<!--alpha漸變透明度動畫
fromAlpha 代表起始時透明度
toAlpha 代表終止時透明度
duration 動畫持續事件 毫秒為單位-->
<alpha
android:fromAlpha="0.0"
android:toAlpha="1.0"
android:duration="1000"/>
</set>
旋轉動畫
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<!--旋轉動畫
interpolator 動畫插值器,跟伸縮動畫一樣
fromDegress 動畫起始時物件的角度
toDegress 動畫結束時物件旋轉的角度,當角度為負數表示逆時針旋轉,當角度為正數表示順時針旋轉
(負數from——to正數:順時針旋轉)
(負數from——to負數:逆時針旋轉)
(正數from——to正數:順時針旋轉)
(正數from——to負數:逆時針旋轉)
pivotX,pivotY表示旋轉的x,y坐標,0%-100%取值。50%表示中點
repeatMode代表重復類型:重復類型有兩個值,reverse表示倒序回放,restart表示從頭播放
repeatCount代表重復次數,重復次數是int型
-->
<rotate
android:duration="3000"
android:fromDegrees="0"
android:interpolator="@android:anim/accelerate_decelerate_interpolator"
android:pivotX="50%"
android:pivotY="50%"
android:toDegrees="+350"
android:repeatMode="restart"
android:repeatCount="6"
/>
</set>
尺寸伸縮動畫
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<!--漸變尺寸伸縮動畫
duration 漸變時間
interpolator 指定一個動畫的插入器
有三種動畫的插入器
accelerate_decelerate_interpolator 加速-減速動畫插入器
accelerate_interpolator 加速動畫插入器
decelerate_interpolator 減速動畫插入器
fromXScale 動畫起始時x坐標的伸縮尺寸
toXScale 動畫結束時x坐標的伸縮尺寸
fromYScale 動畫起始時Y坐標的伸縮尺寸
toYScale 動畫結束時Y坐標的伸縮尺寸
0.0表示沒有,1.0表示正常無收縮,值小于1.0表示收縮,值大于1.0表示放大
pivotX 屬性為動畫相對于物件的X坐標的開始位置
pivotY 屬性為動畫相對于物件的Y坐標的開始位置
從0%-100%開始取值, 50%表示物件的X或者Y方向坐標上的中點位置
fillAfter 當設置為true,該動畫轉化在動畫結束后被應用-->
<scale
android:duration="1000"
android:fillAfter="false"
android:fromXScale="0.0"
android:fromYScale="0.0"
android:toXScale="1.4"
android:toYScale="1.4"
android:pivotX="50%"
android:pivotY="50%"
android:interpolator="@android:anim/accelerate_decelerate_interpolator"/>
</set>
位移動畫
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<!--位置轉移動畫
fromXDelta 動畫開始時X坐標位置
fromYDelta 動畫開始時Y坐標位置
toXDelta 動畫結束時X坐標位置
toYDelta 動畫結束時Y坐標位置
-->
<translate
android:duration="2000"
android:fromXDelta="30"
android:fromYDelta="30"
android:toXDelta="-80"
android:toYDelta="300"
/>
</set>
載入XML動畫效果
switch (v.getId()) {
case R.id.bt_alpha:
//載入動畫
mAnimation = AnimationUtils.loadAnimation(this, R.anim.alpha_anim);
mIv.startAnimation(mAnimation);
break;
case R.id.bt_scale:
//載入動畫
mAnimation = AnimationUtils.loadAnimation(this, R.anim.scale_anim);
mIv.startAnimation(mAnimation);
break;
case R.id.bt_translate:
//載入動畫
mAnimation = AnimationUtils.loadAnimation(this, R.anim.translate_anim);
mIv.startAnimation(mAnimation);
break;
case R.id.bt_rotate:
//載入動畫
mAnimation = AnimationUtils.loadAnimation(this, R.anim.rotate_anim);
mIv.startAnimation(mAnimation);
break;
default:
break;
}
和點擊事件一樣,動畫也具有監聽,只需要我們的activity實現AnimationListener接口就行,我們可以在動畫開始或者結束或者重復做一些別的操作
@Override
public void onAnimationStart(Animation animation) {//動畫開始
}
@Override
public void onAnimationEnd(Animation animation) {//動畫結束
}
@Override
public void onAnimationRepeat(Animation animation) {//動畫重復
}
此外動畫還有其他的屬性,比如比較常用的android:repeatCount(XML中定義,表示重復次數),android:repeatMode(表示重復模式,重復類型有兩個值,reverse表示倒序回放,restart表示從頭播放),android:interpolator(設置差值器,這個在屬性動畫中會詳細講解)
上面講了View動畫的XML實現方式,下面介紹javacode實現方式,javacode的實現方式也很簡單(不需要新建XML)
switch (v.getId()) {
case R.id.bt_alpha:
mAnimation = new AlphaAnimation(0.1f, 0.1f);//新建一個透明度變化的動畫
mAnimation.setDuration(2000);//設置動畫事件
mIv.startAnimation(mAnimation);//開始動畫
break;
case R.id.bt_scale:
//漸變尺寸縮放動畫效果
mAnimation = new ScaleAnimation(0.0f, 2.0f, 1.5f, 1.5f, Animation.RELATIVE_TO_PARENT, 0.5f, Animation.RELATIVE_TO_PARENT, 0.0f);
mAnimation.setDuration(2000);
mIv.startAnimation(mAnimation);
break;
case R.id.bt_translate:
//移動動畫效果
mAnimation = new TranslateAnimation(0, 100, 0, 100);
mAnimation.setDuration(2000);
mIv.startAnimation(mAnimation);
break;
case R.id.bt_rotate:
//旋轉動畫效果,這里是旋轉360°
mAnimation = new RotateAnimation(0.0f, 360.0f, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
mAnimation.setDuration(2000);
mIv.startAnimation(mAnimation);
break;
default:
break;
看效果
2.Drawable Animation動畫,它是把一幀一幀拼起來組成動畫
- 在res/drawable目錄添加圖片素材
-
在drawable文件夾中添加動畫幀布局文件
<?xml version="1.0" encoding="utf-8"?> <!-- 根標簽為animation-list,其中oneshot代表著是否只展示一遍,設置為false會不停的循環播放動畫 根標簽下,通過item標簽對動畫中的每一個圖片進行聲明 android:duration 表示展示所用的該圖片的時間長度 --> <animation-list xmlns:android="http://schemas.android.com/apk/res/android" android:oneshot="false" > <item android:drawable="@drawable/cmmusic_progress_1" android:duration="150"> </item> <item android:drawable="@drawable/cmmusic_progress_2" android:duration="150"> </item> <item android:drawable="@drawable/cmmusic_progress_3" android:duration="150"> </item> <item android:drawable="@drawable/cmmusic_progress_4" android:duration="150"> </item> <item android:drawable="@drawable/cmmusic_progress_5" android:duration="150"> </item> <item android:drawable="@drawable/cmmusic_progress_6" android:duration="150"> </item> <item android:drawable="@drawable/cmmusic_progress_7" android:duration="150"> </item> <item android:drawable="@drawable/cmmusic_progress_8" android:duration="150"> </item> </animation-list>
引入XML布局文件實現動畫
//給ImageView設置drawable
imgPic.setImageResource(R.drawable.loading_anim);
//給動畫資源賦值
animationDrawable = (AnimationDrawable) imgPic.getDrawable();
animationDrawable.start();//開始動畫
animationDrawable.stop(); //停止動畫
實現效果類似于下拉加載的菊花轉
3.屬性動畫
之所以引入屬性動畫有三點原因:
- 屬性動畫不僅可以對view操作,也能對非view的對象進行操作
- 屬性動畫不單單具有View動畫的那些基本動畫效果,也具有其他動畫效果
- View動畫只是改變了View的顯示效果而已,而不會真正去改變View的屬性。而屬性動畫不單單是一種視覺上的動畫,它是真正的改變了view的位置
屬性動畫實際上是一種不斷地對值進行操作的機制,并將值賦值到指定對象的指定屬性上,可以是任意對象的任意屬性。所以我們仍然可以將一個View進行移動或者縮放,但同時也可以對自定義View中的Point對象進行動畫操作了。我們只需要告訴系統動畫的運行時長,需要執行哪種類型的動畫,以及動畫的初始值和結束值,剩下的工作就可以全部交給系統去完成了。
看完上面這段話還是不理解屬性動畫,那我們用起來就可以了
屬性動畫有三個類特別重要,分別是ValueAnimator,ObjectAnimator,AnimatorSet,前兩個都是動畫的執行類,用來執行屬性動畫的,而且ObjectAnimator是集成ValueAnimator的,而AnimatorSet顧名思義是動畫的集合,用它來實現組合動畫,我們來分別認識這三個類
VlaueAnimator
這個是屬性動畫最核心的類了,前面已經提到,屬性動畫實際上是一種不斷對值進行操作的機制,并將值賦值到指定對象的指定屬性上,而初始值和結束值的動畫過渡就是這個類來負責計算的,我們只需要將初始值和結束值提供給ValueAnimator,并且告訴它動畫所需運行的時長,那么ValueAnimator就會自動幫我們完成從初始值平滑地過渡到結束值這樣的效果。除此之外,ValueAnimator還負責管理動畫的播放次數、播放模式、以及對動畫設置監聽器等。
使用ValueAnimator
ValueAnimator anim = ValueAnimator.ofFloat(0f, 1f); //值從0平滑到1,除此之外還可以用ofInt方法
anim.setDuration(300); //動畫持續時間
anim.start(); //動畫開始
但是這段代碼看不到任何界面效果,我們可以添加一個監聽器方法,在動畫執行過程中用不斷進行回調
anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
float currentValue = (float) animation.getAnimatedValue();
Log.d("TAG", "cuurent value is " + currentValue);
}
});
可以通過日志看到動畫確實在執行
ObjectAnimator
ValueAnimator只是實現值的平滑過渡,使用場景并不是很多,而ObjectAnimator可以對任意對象的任意屬性進行操作,一般我們是對view進行操作,因為ObjectAnimator是繼承ValueAnimator,所以在ValueAnimator使用的方法在ObjectAnimator中也可以正常使用,直接上代碼
float curTrans = mIv.getTranslationX();//得到
ObjectAnimator animator = ObjectAnimator.ofFloat(mIv, "translationX", curTrans,-500 ,curTrans);
animator.setDuration(5000);
animator.start();
上面的代碼實現了平移的操作,其他例如透明度變化,旋轉和伸縮都類似,不同的是ofFloat里面的參數發生變化
- ObjectAnimator animator = ObjectAnimator.ofFloat(textview, "alpha", 1f, 0f, 1f); //透明度變化
- ObjectAnimator animator = ObjectAnimator.ofFloat(textview, "rotation", 0f, 360f); //旋轉
- ObjectAnimator animator = ObjectAnimator.ofFloat(textview, "scaleY", 1f, 3f, 1f); 縮放
第一個參數是view,第二個參數是動畫類型,后面的參數根據動畫類型的不同參數也不一樣,關于第二個類型,雖然view里面沒有alpha或者rotation這些屬性,但是有get和set方法,其實ObjectAnimator內部的工作機制并不是直接對我們傳入的屬性名進行操作的,而是會去尋找這個屬性名對應的get和set方法。
AnimatorSet
AnimatorSet是用來實現組合動畫的,比如我們要進行一組組合動畫,先進行位移操作,再進行旋轉操作,再進行淡入淡出的操作,代碼如下:
ObjectAnimator moveIn = ObjectAnimator.ofFloat(textview, "translationX", -500f, 0f); //位移動畫
ObjectAnimator rotate = ObjectAnimator.ofFloat(textview, "rotation", 0f, 360f); //旋轉動畫
ObjectAnimator fadeInOut = ObjectAnimator.ofFloat(textview, "alpha", 1f, 0f, 1f); //淡入淡出動畫
AnimatorSet animSet = new AnimatorSet(); //新建一個AnimatorSet對象
animSet.play(rotate).with(fadeInOut).after(moveIn); //AnimatorSet有一個play方法,動畫執行順序
animSet.setDuration(5000); //動畫持續時間
animSet.start(); //動畫開始