在Android開發中,UI的變化很是常見,若是不使用動畫來進行過分,那麼用戶體驗就會不怎麼好。我將動畫分爲大三類View動畫、幀動畫、屬性動畫三種,下面先從View動畫開始java
View動畫包括如下幾種android
而且還提供了一個AnimationSet類來把多個View動畫進行組合顯示,咱們能夠直接在代碼中建立這些Animation對象也能夠在xml中進行指定bash
縮放動畫ide
ScaleAnimation sAnimation = new ScaleAnimation(0, 1, 0,
1, Animation.RELATIVE_TO_SELF, 0.5f,
Animation.RELATIVE_TO_SELF, 0.5f);
animation.setDuration(2000);
imageView.startAnimation(sAnimation);
複製代碼
<scale xmlns:android="http://schemas.android.com/apk/res/android" android:fromXScale="0" android:toXScale="1" android:fromYScale="0" android:toYScale="1" android:pivotX="50%" android:pivotY="50%" android:duration="2000">
</scale>
複製代碼
平移動畫post
TranslateAnimation tAnimation = new TranslateAnimation(0, 100, 0, 100);
tAnimation.setDuration(2000);
imageView.startAnimation(tAnimation);
複製代碼
<translate xmlns:android="http://schemas.android.com/apk/res/android" android:duration="2000" android:fromXDelta="0" android:toXDelta="200" android:fromYDelta="0" android:toYDelta="200">
</translate>
imageView.startAnimation(AnimationUtils.loadAnimation(this, R.anim.translate));
複製代碼
透明度動畫動畫
AlphaAnimation aAnimation = new AlphaAnimation(0, 1);
aAnimation.setDuration(2000);
imageView.startAnimation(aAnimation);
複製代碼
<alpha xmlns:android="http://schemas.android.com/apk/res/android" android:duration="2000" android:fromAlpha="0" android:toAlpha="1">
</alpha>
複製代碼
旋轉動畫this
RotateAnimation rAnimation = new RotateAnimation(0, 360, Animation.RELATIVE_TO_SELF, 0.5f,
Animation.RELATIVE_TO_SELF, 0.5f);
rAnimation.setDuration(2000);
imageView.startAnimation(rAnimation);
複製代碼
<rotate xmlns:android="http://schemas.android.com/apk/res/android" android:duration="2000" android:fromDegrees="0" android:toDegrees="360">
</rotate>
複製代碼
組合動畫spa
AnimationSet set = new AnimationSet(true);
set.addAnimation(sAnimation);
set.addAnimation(aAnimation);
set.addAnimation(tAnimation);
set.addAnimation(rAnimation);
// 全部子動畫都會被設置成該超時時間
set.setDuration(5000);
imageView.startAnimation(set);
複製代碼
<set xmlns:android="http://schemas.android.com/apk/res/android">
<alpha android:duration="2000" android:fromAlpha="0" android:toAlpha="1">
</alpha>
<rotate android:duration="2000" android:fromDegrees="0" android:toDegrees="360">
</rotate>
<scale android:fromXScale="0" android:toXScale="1" android:fromYScale="0" android:toYScale="1" android:pivotX="50%" android:pivotY="50%" android:duration="2000">
</scale>
<translate android:duration="2000" android:fromXDelta="0" android:toXDelta="200" android:fromYDelta="0" android:toYDelta="200">
</translate>
</set>
複製代碼
以上代碼有幾個須要注意3d
AnimationUtils.loadAnimation(context, resId))
拿到對應的Animation對象startOffset
repeatCount
setFillAfter
設置爲true,可是雖然執行完後保留在了執行完後的位置可是該位置並不能響應點擊事件,原位置可以響應點擊事件AccelerateDecelerateInterpolator
,若是想要動畫按照不停的速率運行,那麼能夠設置如下幾種插值器插值器類 | 對應xml資源id | 變化方式 |
---|---|---|
AccelerateDecelerateInterpolator | @android:anim/accelerate_decelerate_interpolator | 先加速後減速 |
AccelerateInterpolator | @android:anim/accelerate_interpolator | 一直加速 |
AnticipateInterpolator | @android:anim/anticipate_interpolator | 先往反方向運動一段距離再前進 |
AnticipateOvershootInterpolator | @android:anim/anticipate_overshoot_interpolator | 先往反方向運動再前進而且超過目標點,最後回到目標點 |
BounceInterpolator | @android:anim/bounce_interpolator | 相似球落地時的反彈效果 |
CycleInterpolator | @android:anim/cycle_interpolatorr | 循環,先往正向運動到終點,而後向反方向運動知道運動到-終點處再回來 |
DecelerateInterpolator | @android:anim/decelerate_interpolator | 一直減速 |
LinearInterpolator | @android:anim/linear_interpolator | 勻速運動 |
OvershootInterpolator | @android:anim/overshoot_interpolator | 移動超過目標點,而後再回來 |
若是一個ViewGroup被設置了該屬性那麼在第一次顯示該ViewGroup時會執行所設置的動畫,用法以下。code
首先定義一個AnimationSet
<set xmlns:android="http://schemas.android.com/apk/res/android">
<alpha android:duration="2000" android:fromAlpha="0" android:toAlpha="1">
</alpha>
<translate android:duration="2000" android:fromYDelta="100%p" android:toYDelta="0">
</translate>
</set>
複製代碼
而後再res/anim裏面創建一個根節點爲layoutAnimation文件,引用上述的文件,其中的delay表示對應ViewGroup中的每一個View都要延遲動畫duration * delay的時間,如今動畫持續時間是2000ms,那麼第一個item就會在600ms的時候執行動畫,第二個會在1200ms的時候執行
<layoutAnimation xmlns:android="http://schemas.android.com/apk/res/android" android:animationOrder="normal" android:animation="@anim/set" android:delay="0.3">
</layoutAnimation>
複製代碼
最後給目標ViewGroup設置LayoutAnimation
<android.support.v7.widget.RecyclerView android:id="@+id/rv" android:background="@color/colorPrimary" xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:layoutAnimation="@anim/layout_animation" android:orientation="vertical">
</android.support.v7.widget.RecyclerView>
複製代碼
運行效果以下圖所示,固然有點醜,須要的時候能夠慢慢調整
幀動畫就是將一組圖片按照特定的順序進行播放, 使用方式以下所示
<animation-list xmlns:android="http://schemas.android.com/apk/res/android" android:oneshot="true">
<item android:drawable="@drawable/s1" android:duration="1000"/>
<item android:drawable="@drawable/s2" android:duration="1000"/>
<item android:drawable="@drawable/s3" android:duration="1000"/>
<item android:drawable="@drawable/s4" android:duration="1000"/>
<item android:drawable="@drawable/s5" android:duration="1000"/>
<item android:drawable="@drawable/s6" android:duration="5000"/>
<item android:drawable="@drawable/s7" android:duration="1000"/>
</animation-list>
imageView.setImageResource(R.drawable.list);
mDrawable = (AnimationDrawable)imageView.getDrawable();
imageView.post(new Runnable() {
@Override
public void run() {
mDrawable.start();
}
});
複製代碼
這裏有幾個注意點
oneshot
表示是否只播放一次,該值默認是false表示循環播放前面講到的View動畫其實並不會真正改變View的屬性好比位置等等,而屬性動畫會真正的改變View的屬性,其主要類包括如下幾個,其中ObjectAnimator繼承於ValueAnimator,先來看看ViewPropertyAnimator
這個類內部實際上是經過ValueAnimator實現的,咱們能夠經過view.animator()
獲得該類的對象
// translation從當前值慢慢的變爲100
imageView.animate().translationX(100);
// translation從當前值慢慢的變爲原來值+100
imageView.animate().translationXBy(100);
// 反轉180度
imageView.animate().rotation(180);
複製代碼
注意咱們不須要手動調用start方法其就會自動運行,默認持續時間是300ms
咱們能夠經過ofInt、ofFloat、ofArgb等獲取到ValueAnimator實例,下面以經過屬性動畫動態改變圖片的高度爲例
在代碼中定義
ValueAnimator vAnimator = ValueAnimator.ofInt(400, 0);
vAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
ViewGroup.LayoutParams params = imageView.getLayoutParams();
params.height = (int) animation.getAnimatedValue();
imageView.setLayoutParams(params);
}
});
vAnimator.setDuration(3000);
vAnimator.start();
複製代碼
在xml中定義
<animator xmlns:android="http://schemas.android.com/apk/res/android" android:valueFrom="400dp" android:valueType="intType" android:valueTo="0dp" android:duration="3000">
</animator>
ValueAnimator vAnimator =
(ValueAnimator) AnimatorInflater.loadAnimator(this, R.animator.animator);
複製代碼
咱們能夠經過ofInt、ofFloat、ofArgb等獲取到ObjectAnimator實例,通常會操做如下幾個屬性
下面以經過屬性動畫動態改變圖片的透明度爲例
在代碼中定義
ObjectAnimator animator = ObjectAnimator.ofFloat(imageView, "alpha", 0, 1);
animator.setDuration(3000);
animator.start();
複製代碼
在xml中定義
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android" android:valueType="floatType" android:duration="3000" android:propertyName="alpha" android:valueFrom="0" android:valueTo="1">
</objectAnimator>
ObjectAnimator animator = (ObjectAnimator)
AnimatorInflater.loadAnimator(this, R.animator.object_animator);
animator.setTarget(imageView);
animator.start();
複製代碼
幾個注意點:
getter
獲取初始化值,而後不停的調用setter
設置,當超過一個參數時第一個就變爲初始值最後一個變成目標值,中間的都是轉接點這個時候能夠不提供setter
方法AnimatorSet相似AnimationSet,做用是把多個屬性動畫組合起來執行
在代碼中定義
ValueAnimator vAnimator =
(ValueAnimator) AnimatorInflater.loadAnimator(this, R.animator.animator);
vAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
ViewGroup.LayoutParams params = imageView.getLayoutParams();
params.height = (int) animation.getAnimatedValue();
imageView.setLayoutParams(params);
}
});
vAnimator.setDuration(3000);
vAnimator.start();
ObjectAnimator oAnimator = (ObjectAnimator)
AnimatorInflater.loadAnimator(this, R.animator.object_animator);
oAnimator.setTarget(imageView);
oAnimator.start();
AnimatorSet set = new AnimatorSet();
// 同時執行
set.playTogether(vAnimator, oAnimator);
// 順序執行
set.playSequentially(vAnimator, oAnimator);
複製代碼
在xml中定義 其中ordering表示同時執行仍是順序執行
<set xmlns:android="http://schemas.android.com/apk/res/android" android:ordering="together">
<animator android:valueFrom="400px" android:valueTo="0px" android:duration="3000" android:valueType="intType">
</animator>
<objectAnimator android:valueType="floatType" android:duration="3000" android:propertyName="alpha" android:valueFrom="0" android:valueTo="1">
</objectAnimator>
</set>
複製代碼
使用PropertyValuesHolder也能實現多動畫同時執行
PropertyValuesHolder holder1 = PropertyValuesHolder.ofFloat("alpha", 0, 1);
PropertyValuesHolder holder2 = PropertyValuesHolder.ofInt("rotation", 0, 360);
ValueAnimator animator = ObjectAnimator.ofPropertyValuesHolder(holder1, holder2);
animator.setDuration(3000);
animator.setTarget(imageView);
animator.start();
複製代碼
Tips: 將ViewGroup的animateLayoutChanges
屬性設置爲true,在添加View或者移除View的時候會有動畫