補間動畫
原理:
通過確定開始和結束時的檢視樣式, 中間動畫的變化過程由系統來補全。
作用物件:
作用於View物件,不可作用於View的顏色,背景等屬性
分類:
- 平移(Translate)
- 縮放(Scale)
- 旋轉(Rotate)
- 透明度(Alpha)
對應的具體實現類
名稱 | 原理 | 實現類 |
---|---|---|
平移動畫(Translate) | 移動檢視的位置 | TranslateAnimation |
縮放動畫(Scale) | 放大或者縮小檢視大小 | ScaleAnimation |
旋轉動畫(Rotate) | 旋轉檢視 | RotateAnimation |
透明動畫(Alpha) | 改變檢視的透明度 | AlphaAnimation |
TIPS:
補間動畫只會改變View的視覺效果圖,在ScalAnimation和TranslateAnimation中,不會改變View在螢幕上的位置,所以就會導致在執行TranslateAniamtion時,點選平移的View不會觸發click監聽,只有點選它原來的位置時才會觸發click監聽。
***4種動畫(包括set組合動畫)共有的屬性:***
Animation屬性 | 解釋 |
---|---|
android:duration | 動畫執行的時間 |
android:fillAfter | 如果為true,那麼動畫執行完就會定格在執行完的那個畫面,也就是動畫的最後一幀,不會恢復到原位。優先於fillBefore值,預設為false |
android:fillBefore | 動畫播放完後,檢視是否會停留在動畫開始的狀態。只有當android:fillEnable為true時,才有效 |
android:fillEnabled | 是否考慮android:fillBefore的值。只要為true時,android:fillBefore的值才會被考慮。 |
android:interpolator | 設定插值器,控制動畫不同時間段的速度,預設是加速減速插值器。 |
android:repeatCount | 動畫重複的次數,所以總共會執行的動畫次數是這個重複次數+1;為infinite時無限重複 |
android:repeatMode | 動畫重複的方式,有兩個值,reverse 和 restart。reverse表示動畫會正反輪流執行;restart |
android:startOffset | 動畫延遲執行的時間,單位是毫秒 |
插值器
插值器 | xml中的值 | 效果 |
---|---|---|
AccelerateDecelerateInterpolator | @android:anim/accelerate_decelerate_interpolator | 加速減速插值器 動畫先加速再減速 |
AccelerateInterpolator | @android:anim/accelerate_interpolator | 加速插值器 動畫速度越來越快 |
DecelerateInterpolator | @android:anim/decelerate_interpolator | 減速插值器 動畫速度越來越慢 |
BounceInterpolator | @android:anim/bounce_interpolator | 回彈插值器 動畫結束會回彈幾下 |
CycleInterpolator | @android:anim/cycle_interpolator | 圓插值器,動畫會重複幾次,動畫的速度沿著正弦曲線變化 |
LinearInterpolator | @android:anim/linear_interpolator | 線性插值器 動畫速度保持勻速 |
AnticipateOvershootInterpolator | @android:anim/anticipate_overshoot_interpolator | 預期預期超調插值器。先往前甩一定的值,然後開始動畫,結束時往後甩一定的值,結束動畫。 |
AnticipateInterpolator | @android:anim/anticipate_interpolator | 預期插值器,動畫開始時會往前甩一下 |
OvershootInterpolator | @android:anim/overshoot_interpolator | 超調插值器 動畫結束時往後甩一下 |
具體使用
在xml中或者java程式碼中。
Translate:
xml初始化
<!--
以下引數是4種動畫效果的公共屬性,即都有的屬性
android:duration="3000" // 動畫持續時間(ms),必須設定,動畫才有效果
android:startOffset ="1000" // 動畫延遲開始時間(ms)
android:fillBefore = “true” // 動畫播放完後,檢視是否會停留在動畫開始的狀態,預設為true
android:fillAfter = “false” // 動畫播放完後,檢視是否會停留在動畫結束的狀態,優先於fillBefore值,預設為false
android:fillEnabled= “true” // 是否應用fillBefore值,對fillAfter值無影響,預設為true
android:repeatMode= “restart” // 選擇重複播放動畫模式,restart代表正序重放,reverse代表倒序回放,預設為restart|
android:repeatCount = “0” // 重放次數(所以動畫的播放次數=重放次數+1),為infinite時無限重複
以下引數是平移動畫特有的屬性
android:fromXDelta="0" // 檢視在水平方向x 移動的起始值
android:toXDelta="100%" // 檢視在水平方向x 移動的結束值
android:fromYDelta="0" // 檢視在豎直方向y 移動的起始值
android:toYDelta="500" // 檢視在豎直方向y 移動的結束值
-->
<translate xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="3000"
android:startOffset ="10"
android:fillBefore = "true"
android:fillAfter = "false"
android:fillEnabled= "false"
android:repeatMode= "restart"
android:repeatCount = "0"
android:interpolator = "@android:anim/bounce_interpolator"
android:fromXDelta="0"
android:toXDelta="100%"
android:fromYDelta="0"
android:toYDelta="100%"/>
//在class中使用:
translateAnimation = AnimationUtils.loadAnimation(this,R.anim.anim_translate)
btn.startAnimation(translateAnimation)
複製程式碼
java程式碼初始化:
~~~
fun initTraslateForCode() : Animation{
//絕對座標
// translateAnimation = TranslateAnimation(0F,100F,0F,100F)
//絕對座標
// translateAnimation = TranslateAnimation(Animation.ABSOLUTE,0F,Animation.ABSOLUTE,150F,Animation.ABSOLUTE,0F,Animation.ABSOLUTE,150F)
//相對於自己的百分比座標
translateAnimation = TranslateAnimation(Animation.RELATIVE_TO_SELF,0F,Animation.RELATIVE_TO_SELF,100F,Animation.RELATIVE_TO_SELF,0F,Animation.RELATIVE_TO_SELF,100F)
//相對於ParentView的百分比座標
// translateAnimation = TranslateAnimation(Animation.RELATIVE_TO_PARENT,0F,Animation.RELATIVE_TO_PARENT,100F,Animation.RELATIVE_TO_PARENT,0F,Animation.RELATIVE_TO_PARENT,100F)
translateAnimation.duration = 3000
return translateAnimation
}
~~~
複製程式碼
TranslateAnimation獨有屬性
TranslateAnimation獨有屬性 | 含義 |
---|---|
android:fromXDelta | 動畫開始時View左上角的X座標,也有三種寫法: 數值:50;百分數:50%;百分數p:50%p。 如果是數值,表示以View的左上角為(0,0),然後加上寫的數值,以這個點作為開始點。 如果為百分數,如50%,表示總左上角(0,0)加上自身高度的50%, 作為開始點。 如果是百分數p,如50%p,表示總左上角(0,0)加上父控制元件高度的50%,作為開始點。 |
android:fromYDelta | 動畫開始時View左上角的Y座標,也有三種寫法 |
android:toXDelta | 動畫結束時View左上角的X座標,也有三種寫法 |
android:toYDelta | 動畫結束時View左上角的Y座標,也有三種寫法 |
Scale:
ScaleAnimation獨有屬性:
ScaleAnimation獨有屬性 | 含義 |
---|---|
android:pivotX | float,縮放起點,或縮放原點的X軸座標。 縮放圍繞這個點執行。 這個座標預設是View的左上角,(0,0) 在XML中的值有三種寫法. |
android:pivotY | float,同上 Y軸座標. 在XML中的值有三種寫法 |
android:fromXScale | float 動畫開始時,X軸上縮放的比例。1表示本身大小。 |
android:fromYScale | float 動畫開始時,Y軸上縮放的比例。1表示本身大小。 |
android:toXScale | float Y動畫結束時,X軸上縮放的比例。1表示本身大小。 |
android:toYScale | float Y動畫結束時,Y軸上縮放的比例。1表示本身大小。 |
Rotate Rotate獨有屬性:
RotateAnimation獨有屬性 | 含義 |
---|---|
android:pivotX | 旋轉動畫的中心的X座標,旋轉圍繞這個點進行,也有三種寫法, |
android:pivotY | 旋轉動畫的中心的Y座標,旋轉圍繞這個點進行,也有三種寫法 |
android:fromDegrees | 動畫開始時的旋轉角度。角度順時針轉增加,逆時針轉減少。 所以根據開始角度和結束角度來判斷是順時針還是逆時針。360度為一圈。 |
android:toDegrees | 動畫結束時的旋轉角度。 |
Alpha Alpha獨有屬性:
AlphaAnimation的獨有屬性 | 含義 |
---|---|
android:fromAlpha | 動畫開始時的透明度 從0.0-1.0 0.0表示完全透明,1.0表示完全不透明 |
android:toAlpha | 動畫結束時的透明度 |
set組合動畫
//anim_set.xml
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="3000">
<rotate
android:pivotX="50%"
android:pivotY="50%"
android:fromDegrees="360"
android:toDegrees="-90"
/>
<alpha
android:fromAlpha="1"
android:toAlpha="0.2"/>
</set>
//java
Animation translateAnimation = AnimationUtils.loadAnimation(this, R.anim.set);
// 步驟2:建立 動畫物件 並傳入設定的動畫效果xml檔案
mButton.startAnimation(translateAnimation);
複製程式碼
java程式碼設定:
// 組合動畫設定
AnimationSet setAnimation = new AnimationSet(true);
// 步驟1:建立組合動畫物件(設定為true)
// 步驟2:設定組合動畫的屬性
// 特別說明以下情況
// 因為在下面的旋轉動畫設定了無限迴圈(RepeatCount = INFINITE)
// 所以動畫不會結束,而是無限迴圈
// 所以組合動畫的下面兩行設定是無效的
setAnimation.setRepeatMode(Animation.RESTART);
setAnimation.setRepeatCount(1);// 設定了迴圈一次,但無效
// 步驟3:逐個建立子動畫(方式同單個動畫建立方式)
// 子動畫1:旋轉動畫
Animation rotate = new RotateAnimation(0,360,Animation.RELATIVE_TO_SELF,0.5f,Animation.RELATIVE_TO_SELF,0.5f);
rotate.setDuration(1000);
rotate.setRepeatMode(Animation.RESTART);
rotate.setRepeatCount(Animation.INFINITE);
// 子動畫2:平移動畫
Animation translate = new TranslateAnimation(TranslateAnimation.RELATIVE_TO_PARENT,-0.5f,
TranslateAnimation.RELATIVE_TO_PARENT,0.5f,
TranslateAnimation.RELATIVE_TO_SELF,0
,TranslateAnimation.RELATIVE_TO_SELF,0);
translate.setDuration(10000);
// 子動畫3:透明度動畫
Animation alpha = new AlphaAnimation(1,0);
alpha.setDuration(3000);
alpha.setStartOffset(7000);
// 子動畫4:縮放動畫
Animation scale1 = new ScaleAnimation(1,0.5f,1,0.5f,Animation.RELATIVE_TO_SELF,0.5f,Animation.RELATIVE_TO_SELF,0.5f);
scale1.setDuration(1000);
scale1.setStartOffset(4000);
// 步驟4:將建立的子動畫新增到組合動畫裡
setAnimation.addAnimation(alpha);
setAnimation.addAnimation(rotate);
setAnimation.addAnimation(translate);
setAnimation.addAnimation(scale1);
複製程式碼
動畫的監聽 補間動畫只需設定開始檢視和結束檢視,中間的動畫過程由系統完成,因此智慧監聽器開始和結束狀態。
animation.setAnimationListener(new Animation.AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {
Log.i(TAG, "動畫開始時做操作: ");
}
@Override
public void onAnimationEnd(Animation animation) {
Log.i(TAG, "動畫重複時做操作: ");
}
@Override
public void onAnimationRepeat(Animation animation) {
Log.i(TAG, "動畫結束時做操作: ");
}
});
複製程式碼
補充:ListView可以設定出場動畫
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#FFFFFF"
android:orientation="vertical" >
<ListView
android:id="@+id/listView1"
android:layoutAnimation="@anim/anim_layout"
// 指定layoutAnimation屬性用以指定子元素的入場動畫
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
複製程式碼
逐幀動畫
作用物件 檢視控制元件(View)
1.如Android的TextView、Button等等
2.不可作用於View元件的屬性,如:顏色、背景、長度等等
複製程式碼
原理
- 將動畫拆分為 幀 的形式,且定義每一幀 = 每一張圖片
- 逐幀動畫的本質:按序播放一組預先定義好的圖片
具體使用 xml:
//knight_attack.xml
<?xml version="1.0" encoding="utf-8"?>
<animation-list
xmlns:android="http://schemas.android.com/apk/res/android"
android:oneshot="true" // 設定是否只播放一次,預設為false>
// item = 動畫圖片資源;duration = 設定一幀持續時間(ms)
<item android:drawable="@drawable/a0" android:duration="100"/>
<item android:drawable="@drawable/a1" android:duration="100"/>
<item android:drawable="@drawable/a2" android:duration="100"/>
<item android:drawable="@drawable/a3" android:duration="100"/>
<item android:drawable="@drawable/a4" android:duration="100"/>
<item android:drawable="@drawable/a5" android:duration="100"/>
<item android:drawable="@drawable/a6" android:duration="100"/>
<item android:drawable="@drawable/a7" android:duration="100"/>
<item android:drawable="@drawable/a8" android:duration="100"/>
<item android:drawable="@drawable/a9" android:duration="100"/>
<item android:drawable="@drawable/a10" android:duration="100"/>
<item android:drawable="@drawable/a11" android:duration="100"/>
<item android:drawable="@drawable/a12" android:duration="100"/>
<item android:drawable="@drawable/a13" android:duration="100"/>
<item android:drawable="@drawable/a14" android:duration="100"/>
<item android:drawable="@drawable/a15" android:duration="100"/>
<item android:drawable="@drawable/a16" android:duration="100"/>
<item android:drawable="@drawable/a17" android:duration="100"/>
<item android:drawable="@drawable/a18" android:duration="100"/>
<item android:drawable="@drawable/a19" android:duration="100"/>
<item android:drawable="@drawable/a20" android:duration="100"/>
<item android:drawable="@drawable/a21" android:duration="100"/>
<item android:drawable="@drawable/a22" android:duration="100"/>
<item android:drawable="@drawable/a23" android:duration="100"/>
<item android:drawable="@drawable/a24" android:duration="100"/>
<item android:drawable="@drawable/a25" android:duration="100"/>
</animation-list>
//java 程式碼:
iv.setImageResource(R.drawable.knight_attack);
// 1. 設定動畫
animationDrawable = (AnimationDrawable) iv.getDrawable();
// 2. 獲取動畫物件
animationDrawable.start();
複製程式碼
在Java程式碼中實現:
animationDrawable = new AnimationDrawable();
for (int i = 0; i <= 25; i++) {
int id = getResources().getIdentifier("a" + i, "drawable", getPackageName());
Drawable drawable = getResources().getDrawable(id);
animationDrawable.addFrame(drawable, 100);
}
animationDrawable.setOneShot(true);
iv.setImageDrawable(animationDrawable);
// 獲取資源物件
animationDrawable.stop();
// 特別注意:在動畫start()之前要先stop(),不然在第一次動畫之後會停在最後一幀,這樣動畫就只會觸發一次
animationDrawable.start();
// 啟動動畫
作者:Carson_Ho
連結:https://www.jianshu.com/p/225fe1feba60
複製程式碼
注意
儘量避免使用尺寸較大的圖片,否則會引起oom
屬性動畫
補間動畫的侷限性:
1.作用物件有侷限性,只能作用在View上,無法對view的屬性進行動哈操作;
2.沒有改變View的屬性,只是改變視覺效果;
3.效果單一,智慧實現平移,選擇,縮放,透明度4中或者這4種組合的動畫
屬性動畫的原理
在一定時間間隔內,通過不斷對值進行改變,並不斷將該值賦給物件的屬性,從而實現該物件在該屬性上的動畫效果
ValueAnimation
- ValueAnimator.ofInt(int values)
將初始值 以整型數值的形式 過渡到結束值,即使整型估值器 - IntEvalutor
private void initValueAnimator() {
// ofInt()作用有兩個
// 1. 建立動畫例項
//2. 將傳入的多個Int引數進行平滑過渡:此處傳入0和1,表示將值從0平滑過渡到1
// 如果傳入了3個Int引數 a,b,c ,則是先從a平滑過渡到b,再從b平滑過渡到C,以此類推
// ValueAnimator.ofInt()內建了整型估值器,直接採用預設的.不需要設定,即預設設定瞭如何從初始值 過渡到 結束值
final ValueAnimator valueAnimator = ValueAnimator.ofInt(0,3);
// 步驟2:設定動畫的播放各種屬性
valueAnimator.setDuration(500);
// 設定動畫延遲播放時間
valueAnimator.setStartDelay(500);
// 設定動畫重複播放次數 = 重放次數+1
// 動畫播放次數 = infinite時,動畫無限重複
valueAnimator.setRepeatCount(0);
// 設定重複播放動畫模式
// ValueAnimator.RESTART(預設):正序重放
// ValueAnimator.REVERSE:倒序回放
valueAnimator.setRepeatMode(ValueAnimator.RESTART);
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
int currentValue = (int) animation.getAnimatedValue();
Log.i("ValueAnimator:" , currentValue +"");
//todo 將值賦值給View的某個繪製屬性,並重新繪製View。
}
});
valueAnimator.start();
}
複製程式碼
結果為:
05-10 22:06:44.078 4618-4618/com.aoyj.animaiton.valueanimationmaster I/ValueAnimator:: 0
05-10 22:06:44.094 4618-4618/com.aoyj.animaiton.valueanimationmaster I/ValueAnimator:: 0
05-10 22:06:44.115 4618-4618/com.aoyj.animaiton.valueanimationmaster I/ValueAnimator:: 0
05-10 22:06:44.133 4618-4618/com.aoyj.animaiton.valueanimationmaster I/ValueAnimator:: 0
05-10 22:06:44.151 4618-4618/com.aoyj.animaiton.valueanimationmaster I/ValueAnimator:: 0
05-10 22:06:44.169 4618-4618/com.aoyj.animaiton.valueanimationmaster I/ValueAnimator:: 0
05-10 22:06:44.187 4618-4618/com.aoyj.animaiton.valueanimationmaster I/ValueAnimator:: 0
05-10 22:06:44.204 4618-4618/com.aoyj.animaiton.valueanimationmaster I/ValueAnimator:: 0
05-10 22:06:44.224 4618-4618/com.aoyj.animaiton.valueanimationmaster I/ValueAnimator:: 0
05-10 22:06:44.241 4618-4618/com.aoyj.animaiton.valueanimationmaster I/ValueAnimator:: 0
05-10 22:06:44.258 4618-4618/com.aoyj.animaiton.valueanimationmaster I/ValueAnimator:: 1
05-10 22:06:44.276 4618-4618/com.aoyj.animaiton.valueanimationmaster I/ValueAnimator:: 1
05-10 22:06:44.294 4618-4618/com.aoyj.animaiton.valueanimationmaster I/ValueAnimator:: 1
05-10 22:06:44.312 4618-4618/com.aoyj.animaiton.valueanimationmaster I/ValueAnimator:: 1
05-10 22:06:44.331 4618-4618/com.aoyj.animaiton.valueanimationmaster I/ValueAnimator:: 1
05-10 22:06:44.347 4618-4618/com.aoyj.animaiton.valueanimationmaster I/ValueAnimator:: 1
05-10 22:06:44.366 4618-4618/com.aoyj.animaiton.valueanimationmaster I/ValueAnimator:: 1
05-10 22:06:44.386 4618-4618/com.aoyj.animaiton.valueanimationmaster I/ValueAnimator:: 2
05-10 22:06:44.405 4618-4618/com.aoyj.animaiton.valueanimationmaster I/ValueAnimator:: 2
05-10 22:06:44.423 4618-4618/com.aoyj.animaiton.valueanimationmaster I/ValueAnimator:: 2
05-10 22:06:44.440 4618-4618/com.aoyj.animaiton.valueanimationmaster I/ValueAnimator:: 2
05-10 22:06:44.459 4618-4618/com.aoyj.animaiton.valueanimationmaster I/ValueAnimator:: 2
05-10 22:06:44.476 4618-4618/com.aoyj.animaiton.valueanimationmaster I/ValueAnimator:: 2
05-10 22:06:44.493 4618-4618/com.aoyj.animaiton.valueanimationmaster I/ValueAnimator:: 2
05-10 22:06:44.511 4618-4618/com.aoyj.animaiton.valueanimationmaster I/ValueAnimator:: 2
05-10 22:06:44.530 4618-4618/com.aoyj.animaiton.valueanimationmaster I/ValueAnimator:: 2
05-10 22:06:44.548 4618-4618/com.aoyj.animaiton.valueanimationmaster I/ValueAnimator:: 2
05-10 22:06:44.567 4618-4618/com.aoyj.animaiton.valueanimationmaster I/ValueAnimator:: 3
複製程式碼
可以將動畫寫在在xml中,但是這樣子value的初始值和結束值都時事先固定的。
//set_anim.xml
<animator xmlns:android="http://schemas.android.com/apk/res/android"
android:valueFrom="0" // 初始值
android:valueTo="100" // 結束值
android:valueType="intType" // 變化值型別 :floatType & intType
android:duration="3000" // 動畫持續時間(ms),必須設定,動畫才有效果
android:startOffset ="1000" // 動畫延遲開始時間(ms)
android:fillBefore = “true” // 動畫播放完後,檢視是否會停留在動畫開始的狀態,預設為true
android:fillAfter = “false” // 動畫播放完後,檢視是否會停留在動畫結束的狀態,優先於fillBefore值,預設為false
android:fillEnabled= “true” // 是否應用fillBefore值,對fillAfter值無影響,預設為true
android:repeatMode= “restart” // 選擇重複播放動畫模式,restart代表正序重放,reverse代表倒序回放,預設為restart|
android:repeatCount = “0” // 重放次數(所以動畫的播放次數=重放次數+1),為infinite時無限重複
android:interpolator = @[package:]anim/interpolator_resource // 插值器,即影響動畫的播放速度,下面會詳細講
/>
//在java程式碼中使用
ValueAnimator valueAnimator = ValueAnimatorInflater.loadAnimator(context,R.anim.set_anim);
valueAnimator.start();
作者:Carson_Ho
連結:https://www.jianshu.com/p/2412d00a0ce4
來源:簡書
複製程式碼
***ValueAnimator.ofFloat()***
與ValueAnimator.ofiInt()類似
ValueAnimator.ofObject()
ValueAnimator.ofInt()與ValueAnimator.ofFloat()都有內建的估值器,ValueAnimator.ofFloat()的估值器FloatEvaluetor實現為:
public class FloatEvaluator implements TypeEvaluator {
// FloatEvaluator實現了TypeEvaluator介面
// 重寫evaluate()
public Object evaluate(float fraction, Object startValue, Object endValue) {
// 引數說明
// fraction:表示動畫完成度(根據它來計算當前動畫的值)
// startValue、endValue:動畫的初始值和結束值
float startFloat = ((Number) startValue).floatValue();
return startFloat + fraction * (((Number) endValue).floatValue() - startFloat);
// 初始值 過渡 到結束值 的演算法是:
// 1. 用結束值減去初始值,算出它們之間的差值
// 2. 用上述差值乘以fraction係數
// 3. 再加上初始值,就得到當前動畫的值
}
}
複製程式碼
對於ValueAnimator.ofObject(),我自定義Evaluetor
public class ObjectEvaluetor implements TypeEvaluetor{
@Override
public Object evaluetor(float fraction,Object startValue,Object endValue){
//fraction 為執行動畫的完成度
//startValue endValue為初始值和結束值
... //計算物件動畫的值
return value;
}
}
複製程式碼
ValueAnimator.ofObject()總結:
ValueAnimator.ofObject()本質還是改變值,只是其可以同時改變一個物件的多個屬性值。而ValueAnimator.ofInt()和ValueAnimator.ofFloat()只能改變一個值。
ObjectAnimator
ObjectAnimato和ValueAnimator本質都是通過不斷改變View的某個值達到動畫效果。不同的是
ValueAnimator是手動給View的某個屬性賦值,而ObjectAnimator是自動給View的屬性賦值。
和ValueAnimator類似,ObjectAnimator也有ObjectAnimator.ofInt(),ObjectAnimator.ofFloat(),ObjectAnimator.ofObject()這些型別,具體使用哪種要根據設定的property決定。
具體使用
java設定:
/**
Object object:需要操作的物件
String property:需要操作的物件的屬性
float ....values:動畫初始值 & 結束值(不固定長度)
若是兩個引數a,b,則動畫效果則是從屬性的a值到b值
若是三個引數a,b,c,則則動畫效果則是從屬性的a值到b值再到c值
**/
ObjectAnimator animator = ObjectAnimator.ofFloat(Object object, String property, float ....values);
// 設定動畫執行的時長
anim.setDuration(500);
// 設定動畫延遲播放時間
anim.setStartDelay(500);
// 設定動畫重複播放次數 = 重放次數+1,動畫播放次數 = infinite時,動畫無限重複
anim.setRepeatCount(0);
// 設定重複播放動畫模式:RESTART(預設):正序重放,REVERSE:倒序回放
anim.setRepeatMode(ValueAnimator.RESTART);
複製程式碼
縮放:
//縮放 java程式碼
fun initAnimator(){
//作用物件是btn
//作用的物件屬性是x軸縮放
//動畫效果是放大到3倍,在縮小到初始值
scaleAnimator = ObjectAnimator.ofFloat(btn,"scaleX",1f,3f,2f)
scaleAnimator.duration = 2000
scaleAnimator.start()
}
//xml scale_animator.xml
<?xml version="1.0" encoding="utf-8"?>
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
android:valueFrom="1"
android:valueType="floatType"
android:propertyName="scaleX"
android:valueTo="3"
android:repeatCount="0"
android:repeatMode="restart"
android:startOffset="100"
android:duration="500">
</objectAnimator>
//java程式碼中使用xml:
ObjectAniamtor scaleAnimator = ValueAnimatorInflater.loadAnimator(context,R.animtor.scale_animator) as ObjectAnimator
scaleAnimator.target = btn
scaleAnimator.start()
複製程式碼
透明度:
//java程式碼:
fun initAnimator(){
alphaAnimator = ObjectAnimator.ofFloat(btn,"alpha",1f,0f,0.5f,1f)
alphaAnimator.duration = 500
alphaAnimator.repeatCount = 0
alphaAnimator.repeatMode = ValueAnimator.RESTART
alphaAniamtor.start()
}
//xml程式碼:alpha_animator.xml
<?xml version="1.0" encoding="utf-8"?>
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
android:valueFrom="1"
android:valueTo="0.5"
android:valueType="floatType"
android:propertyName="alpha"
android:duration="500"
android:startOffset="100"
android:repeatMode="restart"
android:repeatCount="0">
</objectAnimator>
//java 程式碼:
alphaAnimator = AnimatorInflater.loadAnimator(context,R.animator.alpha_animator) as ObjectAnimator
alphaAnimator.target = btn
alphaAnimator.start()
複製程式碼
旋轉
//java 程式碼
fun initAnimator(){
rotationAnimator = ObjectAnimator.ofFloat(btn,"rotation",0f,360f)
rotationAnimator.duration = 500
rotationAnimator.startDelay = 100
rotationAnimator.repeatMode = ValueAnimator.RESTART
rotationAnimator.repeatCount = 0
rotationAniamtor.start()
}
//xml程式碼:rotation_animator.xml
<?xml version="1.0" encoding="utf-8"?>
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
android:valueFrom="0"
android:valueTo="360"
android:valueType="floatType"
android:propertyName="rotation"
android:duration="500"
android:startOffset="100"
android:repeatCount="0"
android:repeatMode="reverse">
</objectAnimator>
//java 應用xml程式碼
rotationAnimator = AnimatorInflater.loadAnimator(context,R.animator.rotation_animator) as ObjectAnimator
rotationAnimator.target = btn
rotationAnimator.start()
複製程式碼
平移:平移的座標系都是以執行動畫的View的左上角座標點為起始點座標
//java程式碼:
fun initAnimator(){
translateAnimator = ObjectAnimator.ofFloat(btn,"translationX",100F,200F)
translateAnimator.duration = 500
translateAnimator.interpolator = BounceInterpolator()
translationAnimator.start()
}
//xml 程式碼
<?xml version="1.0" encoding="utf-8"?>
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
android:valueFrom="0"
android:valueTo="500"
android:valueType="floatType"
android:propertyName="translationX"
android:interpolator="@android:anim/bounce_interpolator"
android:duration="500"
android:startOffset="100"
android:repeatMode="restart"
android:repeatCount="0">
</objectAnimator>
//java 應用xml程式碼
fun initAniamtorFromXml(){
translateAnimator = AnimatorInflater.loadAnimator(this,R.animator.translation_animator) as ObjectAnimator
translateAnimator.target = btn
translateAnimator.start()
}
複製程式碼
ObjectAnimator在一般View上起作用的集中屬性:
View屬性值 | 效果 | 數值型別 |
---|---|---|
alpha | 控制透明度 | float |
translationX | 控制x方向上位移 (以執行動畫的View的左上角為座標原點) |
float(例如:0到50) |
translationY | 控制y方向上位移 (以執行動畫的View的左上角為座標原點) |
float(例:如0到500) |
scaleX | 控制x方向的縮放倍數 (個人認為以View的中心左邊點為縮放點) |
float(例如:1到3) |
scaleY | 控制y方向的縮放倍數 (個人認為以View的中心左邊點為縮放點) |
float(例如:1到3) |
rotation | 以螢幕方向為軸的旋轉 | float(例如:0到360) |
rotationX | 以x軸方向旋轉 | float(例如:0到360) |
rotationY | 以y軸方向旋轉 | float(例如:0到360) |
AnimatorSet組合動畫
AnimatorSet.play(Animator anim) :播放當前動畫
AnimatorSet.after(long delay) :將現有動畫延遲x毫秒後執行
AnimatorSet.with(Animator anim) :將現有動畫和傳入的動畫同時執行
AnimatorSet.after(Animator anim) :將現有動畫插入到傳入的動畫之後執行
AnimatorSet.before(Animator anim) : 將現有動畫插入到傳入的動畫之前執行
複製程式碼
xml:
//set_animator.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:ordering="sequentially" >
// 表示Set集合內的動畫按順序進行
// ordering的屬性值:sequentially & together
// sequentially:表示set中的動畫,按照先後順序逐步進行(a 完成之後進行 b )
// together:表示set中的動畫,在同一時間同時進行,為預設值
<set android:ordering="together" >
// 下面的動畫同時進行
<objectAnimator
android:duration="2000"
android:propertyName="translationX"
android:valueFrom="0"
android:valueTo="300"
android:valueType="floatType" >
</objectAnimator>
<objectAnimator
android:duration="3000"
android:propertyName="rotation"
android:valueFrom="0"
android:valueTo="360"
android:valueType="floatType" >
</objectAnimator>
</set>
<set android:ordering="sequentially" >
// 下面的動畫按序進行
<objectAnimator
android:duration="1500"
android:propertyName="alpha"
android:valueFrom="1"
android:valueTo="0"
android:valueType="floatType" >
</objectAnimator>
<objectAnimator
android:duration="1500"
android:propertyName="alpha"
android:valueFrom="0"
android:valueTo="1"
android:valueType="floatType" >
</objectAnimator>
</set>
</set>
複製程式碼
android 動畫框架
LayoutAnimation
LayoutAnimation是應用於ViewGroup的動畫框架。它可以使VeiwGroup中的childView按照繪製先後,順序執行動畫。
java程式碼設定
//具體執行的animation:
//animation_layout_scale.xml
<?xml version="1.0" encoding="utf-8"?>
<scale xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="300"
android:pivotY="50%"
android:pivotX="50%"
android:fromYScale="0.1"
android:fromXScale="0.1"
android:toXScale="1"
android:toYScale="1">
</scale>
//初始化LayoutAnimationControl
Animation animation = AnimationUtils.loadAnimation(mContext,R.anim.animation_layout_scale);
//第一個引數是具體執行的動畫,第二個引數是layoutAnimation的延時百分比
LayoutAnimationController controller = new LayoutAnimationControl(animation,0.3f);
//設定動畫執行順序
controller.setOrder(LayoutAnimationController.ORDER_NORMAL);
listVeiw.setlayoutAnimation(controller);
複製程式碼
xml實現:
//layout_animation.xml
<?xml version="1.0" encoding="utf-8"?>
<layoutAnimation xmlns:android="http://schemas.android.com/apk/res/android"
android:delay="0.3"
android:animationOrder="normal"
android:animation="@anim/animation_layout_scale">
</layoutAnimation>
//Viewgroup設定LayoutAnimation屬性
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent"
android:layout_height="match_parent">
<ListView
android:id="@+id/list_view"
android:layout_width="match_parent"
android:layoutAnimation="@anim/layout_animation"
android:layout_height="match_parent"/>
</android.support.constraint.ConstraintLayout>
複製程式碼
delay:指的是child view相對於上一個childView動畫的延時時間。取值是具體執行的animation的動畫時間的倍數;
animationOrder:指的是ViewGroup中child view動畫開始的順序。normal(按照正常的繪製順序執行),reverse(按照繪製順序逆序執行),random(隨機執行);
animation:child view具體執行的動畫,只能是補間動畫;
ViewAnimationUtils
android 5.0以上的生成一個圓形動畫的animator;
private void startViewAniamtionUtils(){
int centreX = btn.getWidth();
int centreY = btn.getHeight();
float hypot = (float) Math.hypot(btn.getHeight(), btn.getWidth());
//第一個引數是執行圓形動畫的view,第二,第三個引數是圓心,第四,第五個引數是圓的半徑取值範圍
Animator animator = ViewAnimationUtils.createCircularReveal(btn,centreX,centreY,0,hypot);
animator.setDuration(600);
animator.setStartDelay(10);
// animator.setInterpolator(new LinearInterpolator());
AnimatorSet set = new AnimatorSet();
set.play(animator)
.with(getAlphAnimator());
set.setDuration(600);
set.setInterpolator(new AccelerateInterpolator());
set.start();
}
private ObjectAnimator getAlphAnimator(){
ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(btn,"alpha",0f,1f);
objectAnimator.setDuration(600);
objectAnimator.setTarget(btn);
// objectAnimator.setInterpolator(new LinearInterpolator());
return objectAnimator;
}
複製程式碼
overridePendingTransition
指定Activity的退出和進入動畫,它包括兩個部分
一部分是第一個activity退出時的動畫,
另外一個部分是第二個activity進入時的動畫。
需要注意兩個部分:
- 在android2.0以上呼叫,
- 要在startActivity或者finished的後面呼叫。
@OnClick(R.id.button)
public void onViewClicked() {
finish();
overridePendingTransition(R.anim.enter_anim,R.anim.exit_anim);
}
//enter_anim:
<?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="500"
android:fromXDelta="-30%"
android:toXDelta="0">
</translate>
//exit_anim.xml
<?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="500"
android:fromXDelta="0"
android:toXDelta="100%">
</translate>
複製程式碼
ViewPropertyAnimator
本質上和ValueAniamtor和ObjectAnimator相同,能夠很方便的為view提供動畫。
button2.animate()
.translationXBy(200)
//.translationX(200)
.setDuration(500);
複製程式碼
ViewProperty中帶by的方法含義是,相對於執行動畫View的現有狀態進行動畫,不帶by的方法含義是相對於View最初始狀態進行動畫。translationXBy(200)每次執行動畫,button2的位置都會相對於現有位置平移200px.translationX(200):不管執行多少次動畫,button2的位置都是相對於初始位置平移200px,換句話說button2會在第一次執行動畫時平移200px,後面執行動畫,button2的位置不會發生變化。
SpringAniamtion
這是彈簧動畫;
SpringForce spring = new SpringForce(0)
.setDampingRatio(SpringForce.DAMPING_RATIO_HIGH_BOUNCY)
.setStiffness(SpringForce.STIFFNESS_LOW);
new SpringAnimation(rootLayout, DynamicAnimation.TRANSLATION_Y)
.setSpring(spring)
.setStartValue(-height)
.setStartVelocity(-200)
.start();
複製程式碼
SpringAniamtion可以實現旋轉,平移,縮放,透明度等的動畫。
- setDampingRatio():設定阻尼係數,取值範圍在0 ~ 1之間,值越大彈簧效果越明顯。
- setStiffness(): 設定剛性,取值範圍在0 ~ 1之間。值越小,彈簧震動次數也多。