請給我上一份動畫總結之補間動畫
提起動畫,會有三種動畫類型在Android開發中經常被用到:
- 幀動畫
- 補間動畫
- 屬性動畫
這篇文章主要介紹補間動畫的原理以及使用
原理
通過确定開始的視圖樣式和結束的視圖樣式加入中間動畫變化過程來确定一個動畫
作用對象及使用場景
主要作用于視圖控件(如Button,TextView,ImageView等,與幀動畫一樣)
主要應用于頁面的切換。
補間動畫的使用
補間動畫主要分為:
- 平移動畫(Translate)
- 縮放動畫(Scale)
- 旋轉動畫(Rotate)
- 透明度動畫(Alpha)
以上4種方法均有兩種使用方法:一種是以xml方式,一種是以Java形式。下面分别來介紹這4種動畫的使用
平移動畫(Translate)
方法一:xml方法
首先在res下建立一個anim檔案夾,在anim檔案夾下建立translate.xml檔案,檔案路徑res/anim/translate.xml
translate.xml:
<?xml version="1.0" encoding="utf-8"?>
<!--平移動畫-->
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate
android:duration="3000"
android:fillAfter="false"
android:fillBefore="true"
android:fillEnabled="true"
android:repeatCount="infinite"
android:interpolator = "@android:anim/linear_interpolator"
android:repeatMode="restart"
android:startOffset="1000"
android:fromXDelta="0"
android:toXDelta="500"
android:fromYDelta="0"
android:toYDelta="500" />
</set>
其次在Java代碼中加入啟動動畫代碼:
public class TranslateAnimationActivity extends AppCompatActivity {
private ImageView mImageView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_translate_animation);
// 步驟1:建立 需要設定動畫的 視圖View
mImageView = findViewById(R.id.iv_image);
// 步驟2:建立 動畫對象 并傳入設定的動畫效果xml檔案
Animation translateAnimation = AnimationUtils.loadAnimation(this, R.anim.translate);
// 步驟3:播放動畫
mImageView.startAnimation(translateAnimation);
}
}
結果展示:
方法二:Java方法
public class TranslateAnimationActivity extends AppCompatActivity {
private ImageView mImageView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_translate_animation);
// 步驟1:建立 需要設定動畫的 視圖View
mImageView = findViewById(R.id.iv_image);
/*
建立平移動畫的對象:平移動畫對應的Animation子類為TranslateAnimation
TranslateAnimation 有三個構造方法
public TranslateAnimation(Context context, AttributeSet attrs) {}
public TranslateAnimation(float fromXDelta, float toXDelta, float fromYDelta, float toYDelta) {}
public TranslateAnimation(int fromXType, float fromXValue, int toXType, float toXValue, int fromYType, float fromYValue, int toYType, float toYValue) {}
參數分别是:
1. fromXDelta :視圖在水準方向x 移動的起始值
2. toXDelta :視圖在水準方向x 移動的結束值
3. fromYDelta :視圖在豎直方向y 移動的起始值
4. toYDelta:視圖在豎直方向y 移動的結束值
5. pivotXType:平移軸點的x坐标的模式
6. pivotXValue:平移軸點x坐标的相對值
7. pivotYType:平移軸點的y坐标的模式
8. pivotYValue:平移軸點y坐标的相對值
*/
Animation translateAnimation = new TranslateAnimation(, , , );
// 固定屬性的設定都是在其屬性前加“set”,如setDuration()
translateAnimation.setDuration();
translateAnimation.setRepeatCount(Animation.INFINITE);
// 步驟3:播放動畫
mImageView.startAnimation(translateAnimation);
}
}
效果圖同上
縮放動畫(Scale)
方法一:xml方法
首先在res下建立一個anim檔案夾,在anim檔案夾下建立scale.xml檔案,檔案路徑res/anim/scale.xml
scale.xml:
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<scale
android:duration="3000"
android:fillAfter="false"
android:fillBefore="true"
android:fillEnabled="true"
android:repeatCount="infinite"
android:interpolator = "@android:anim/linear_interpolator"
android:repeatMode="restart"
android:startOffset="1000"
android:fromXScale="0"
android:fromYScale="0"
android:toXScale="5"
android:toYScale="5"
android:pivotX="50%"
android:pivotY="50%"/>
</set>
其次在Java代碼中加入啟動動畫代碼:
public class ScaleAnimationActivity extends AppCompatActivity {
private ImageView mIvImage;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_scale_animation);
mIvImage = findViewById(R.id.iv_image);
//傳入xml檔案
Animation animation = AnimationUtils.loadAnimation(this, R.anim.scale);
//開始動畫
mIvImage.startAnimation(animation);
}
}
結果展示:
方法二:Java方法
public class ScaleAnimationActivity extends AppCompatActivity {
private ImageView mIvImage;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_scale_animation);
mIvImage = findViewById(R.id.iv_image);
/*
建立縮放動畫的對象 & 設定動畫效果:縮放動畫對應的Animation子類為ScaleAnimation
ScaleAnimation 有四種構造方法
public ScaleAnimation(Context context, AttributeSet attrs) {}
public ScaleAnimation(float fromX, float toX, float fromY, float toY) {}
public ScaleAnimation(float fromX, float toX, float fromY, float toY, float pivotX, float pivotY) {}
public ScaleAnimation(float fromX, float toX, float fromY, float toY, int pivotXType, float pivotXValue, int pivotYType, float pivotYValue) {}
參數說明:
1. fromX :動畫在水準方向X的結束縮放倍數
2. toX :動畫在水準方向X的結束縮放倍數
3. fromY :動畫開始前在豎直方向Y的起始縮放倍數
4. toY:動畫在豎直方向Y的結束縮放倍數
5. pivotXType:縮放軸點的x坐标的模式
6. pivotXValue:縮放軸點x坐标的相對值
7. pivotYType:縮放軸點的y坐标的模式
8. pivotYValue:縮放軸點y坐标的相對值
pivotXType = Animation.ABSOLUTE:縮放軸點的x坐标 = View左上角的原點 在x方向 加上 pivotXValue數值的點(y方向同理)
pivotXType = Animation.RELATIVE_TO_SELF:縮放軸點的x坐标 = View左上角的原點 在x方向 加上 自身寬度乘上pivotXValue數值的值(y方向同理)
pivotXType = Animation.RELATIVE_TO_PARENT:縮放軸點的x坐标 = View左上角的原點 在x方向 加上 父控件寬度乘上pivotXValue數值的值 (y方向同理)
*/
Animation animation = new ScaleAnimation(, , , , f, f);
animation.setDuration();
animation.setRepeatCount(Animation.INFINITE);
mIvImage.startAnimation(animation);
}
}
效果圖同上
旋轉動畫(Rotate)
方法一:xml方法
首先在res下建立一個anim檔案夾,在anim檔案夾下建立rotate.xml檔案,檔案路徑res/anim/rotate.xml
rotate.xml:
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<rotate
android:duration="3000"
android:fillAfter="false"
android:fillBefore="true"
android:fillEnabled="true"
android:repeatCount="infinite"
android:interpolator = "@android:anim/linear_interpolator"
android:repeatMode="restart"
android:startOffset="1000"
android:fromDegrees="0"
android:toDegrees="360"
android:pivotX="50%"
android:pivotY="50%"
/>
</set>
其次在Java代碼中加入啟動動畫代碼:
public class RotateAnimationActivity extends AppCompatActivity {
private ImageView mIvImage;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_rotate_animation);
mIvImage = findViewById(R.id.iv_image);
//傳入xml
Animation animation = AnimationUtils.loadAnimation(this, R.anim.rotate);
//開始動畫
mIvImage.startAnimation(animation);
}
}
結果展示:
方法二:Java方法
public class RotateAnimationActivity extends AppCompatActivity {
private ImageView mIvImage;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_rotate_animation);
mIvImage = findViewById(R.id.iv_image);
/*
建立旋轉動畫的對象 & 設定動畫效果:旋轉動畫對應的Animation子類為RotateAnimation
RotateAnimation 有四種構造方法
public RotateAnimation(Context context, AttributeSet attrs) {}
public RotateAnimation(float fromDegrees, float toDegrees) {}
public RotateAnimation(float fromDegrees, float toDegrees, float pivotX, float pivotY) {}
public RotateAnimation(float fromDegrees, float toDegrees, int pivotXType, float pivotXValue, int pivotYType, float pivotYValue) {}
參數說明:
1. fromDegrees :動畫開始時 視圖的旋轉角度(正數 = 順時針,負數 = 逆時針)
2. toDegrees :動畫結束時 視圖的旋轉角度(正數 = 順時針,負數 = 逆時針)
3. pivotXType:旋轉軸點的x坐标的模式
4. pivotXValue:旋轉軸點x坐标的相對值
5. pivotYType:旋轉軸點的y坐标的模式
6. pivotYValue:旋轉軸點y坐标的相對值
pivotXType = Animation.ABSOLUTE:旋轉軸點的x坐标 = View左上角的原點 在x方向 加上 pivotXValue數值的點(y方向同理)
pivotXType = Animation.RELATIVE_TO_SELF:旋轉軸點的x坐标 = View左上角的原點 在x方向 加上 自身寬度乘上pivotXValue數值的值(y方向同理)
pivotXType = Animation.RELATIVE_TO_PARENT:旋轉軸點的x坐标 = View左上角的原點 在x方向 加上 父控件寬度乘上pivotXValue數值的值 (y方向同理)
*/
Animation animation = new RotateAnimation(, ,Animation.RELATIVE_TO_SELF,f,Animation.RELATIVE_TO_SELF, f);
animation.setRepeatCount(Animation.INFINITE);
animation.setDuration();
mIvImage.startAnimation(animation);
}
}
效果圖同上
透明度動畫(Alpha)
方法一:xml方法
首先在res下建立一個anim檔案夾,在anim檔案夾下建立alpha.xml檔案,檔案路徑res/anim/alpha.xml
alpha.xml:
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<alpha
android:duration="1000"
android:fillAfter="false"
android:fillBefore="true"
android:fillEnabled="true"
android:repeatCount="infinite"
android:interpolator = "@android:anim/linear_interpolator"
android:repeatMode="restart"
android:startOffset="1000"
android:fromAlpha="1"
android:toAlpha="0"/>
</set>
其次在Java代碼中加入啟動動畫代碼:
public class AlphaAnimationActivity extends AppCompatActivity {
private ImageView mIvImage;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_alpha_animation);
mIvImage = findViewById(R.id.iv_image);
Animation animation = AnimationUtils.loadAnimation(this, R.anim.alpha);
mIvImage.startAnimation(animation);
}
}
結果展示:
方法二:Java方法
public class AlphaAnimationActivity extends AppCompatActivity {
private ImageView mIvImage;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_alpha_animation);
mIvImage = findViewById(R.id.iv_image);
/*
建立透明度動畫的對象 & 設定動畫效果:透明度動畫對應的Animation子類為AlphaAnimation
AlphaAnimation 有兩個構造方法
public AlphaAnimation(Context context, AttributeSet attrs) {}
public AlphaAnimation(float fromAlpha, float toAlpha) {}
參數說明:
1. fromAlpha:動畫開始時視圖的透明度(取值範圍: -1 ~ 1)
2. toAlpha:動畫結束時視圖的透明度(取值範圍: -1 ~ 1)
*/
Animation animation = new AlphaAnimation(, );
animation.setDuration();
animation.setRepeatCount(Animation.INFINITE);
mIvImage.startAnimation(animation);
}
}
效果圖同上
寫到這裡,四種動畫的使用就介紹完了,其中Java代碼中需要使用的動畫子類我已經在代碼中添加了注釋,下面介紹一下在xml檔案中四種動畫擁有一部分共有的屬性和另一部分自帶的屬性
共有屬性:
android:duration="3000" // 動畫持續時間(ms),必須設定,動畫才有效果
android:fillAfter="false"// 動畫播放完後,視圖是否會停留在動畫結束的狀态,優先于fillBefore值,預設為false
android:fillBefore="true"// 動畫播放完後,視圖是否會停留在動畫開始的狀态,預設為true
android:fillEnabled="true"// 是否應用fillBefore值,對fillAfter值無影響,預設為true
android:repeatCount="infinite"// 重放次數(是以動畫的播放次數=重放次數+1),為infinite時無限重複
android:interpolator = "@android:anim/linear_interpolator"// 插值器,即影響動畫的播放速度
android:repeatMode="restart"// 選擇重複播放動畫模式,restart代表正序重放,reverse代表倒序回放,預設為restart|
android:startOffset="1000"// 動畫延遲開始時間(ms)
平移動畫特有屬性:
android:fromXDelta="0"// 視圖在水準方向x 移動的起始值
android:toXDelta="500"// 視圖在水準方向x 移動的結束值
android:fromYDelta="0"// 視圖在豎直方向y 移動的起始值
android:toYDelta="500"// 視圖在豎直方向y 移動的結束值
縮放動畫特有屬性:
//這裡0表示收縮到沒有;1表示正常無伸縮,值小于1表示收縮;值大于1表示放大
android:fromXScale="0"// 動畫在水準方向X的起始縮放倍數,
android:fromYScale="0"// 動畫在豎直方向y的起始縮放倍數,
android:toXScale="5"//動畫在水準方向X的結束縮放倍數
android:toYScale="5"//動畫在豎直方向y的結束縮放倍數
android:pivotX="50%"// 縮放軸點的x坐标
android:pivotY="50%"// 縮放軸點的y坐标
/*設定為數字時(如50),軸點為View的左上角的原點在x方向和y方向加上50px的點。在Java代碼裡面設定這個參數的對應參數是Animation.ABSOLUTE。
設定為百分比時(如50%),軸點為View的左上角的原點在x方向加上自身寬度50%和y方向自身高度50%的點。在Java代碼裡面設定這個參數的對應參數是Animation.RELATIVE_TO_SELF
設定為百分比p時(如50%p),軸點為View的左上角的原點在x方向加上父控件寬度50%和y方向父控件高度50%的點。在Java代碼裡面設定這個參數的對應參數是Animation.RELATIVE_TO_PARENT
*/
旋轉動畫特有屬性:
android:fromDegrees="0"// 動畫開始時 視圖的旋轉角度(正數 = 順時針,負數 = 逆時針)
android:toDegrees="360"// 動畫結束時 視圖的旋轉角度(正數 = 順時針,負數 = 逆時針)
android:pivotX="50%"// 縮放軸點的x坐标
android:pivotY="50%"// 縮放軸點的y坐标
透明度動畫特有屬性:
android:fromAlpha="1"// 動畫開始時視圖的透明度(取值範圍: -1 ~ 1)
android:toAlpha="0"// 動畫結束時視圖的透明度(取值範圍: -1 ~ 1)
插值器
具體動畫可參考文章
組合動畫
方法一:xml方法
首先在res下建立一個anim檔案夾,在anim檔案夾下建立group.xml檔案,檔案路徑res/anim/group.xml
group.xml:
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="3000"
android:fillAfter="true"
android:fillBefore="false"
android:fillEnabled="false"
android:interpolator="@android:anim/linear_interpolator"
android:repeatMode="restart"
android:startOffset="1000">
<rotate
android:duration="3000"
android:fromDegrees="0"
android:interpolator="@android:anim/linear_interpolator"
android:pivotX="50%"
android:pivotY="50%"
android:repeatCount="infinite"
android:repeatMode="restart"
android:startOffset="100"
android:toDegrees="360" />
<translate
android:duration="1000"
android:fromXDelta="0"
android:fromYDelta="0"
android:startOffset="0"
android:toXDelta="500"
android:toYDelta="500" />
<alpha
android:duration="5000"
android:fromAlpha="1"
android:interpolator="@android:anim/linear_interpolator"
android:startOffset="2000"
android:toAlpha="0" />
</set>
其次在Java代碼中加入啟動動畫代碼:
public class GroupAnimationActivity extends AppCompatActivity {
private ImageView mIvImage;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_group_animation);
mIvImage = findViewById(R.id.iv_image);
Animation animation = AnimationUtils.loadAnimation(this, R.anim.group);
mIvImage.startAnimation(animation);
}
}
結果展示:
方法二:Java方法
public class GroupAnimationActivity extends AppCompatActivity {
private ImageView mIvImage;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_group_animation);
mIvImage = findViewById(R.id.iv_image);
// 組合動畫設定
// 步驟1:建立組合動畫對象(設定為true)
AnimationSet setAnimation = new AnimationSet(true);
// 步驟2:設定組合動畫的屬性
setAnimation.setRepeatMode(Animation.RESTART);
setAnimation.setStartOffset();
setAnimation.setDuration();
// 步驟3:逐個建立子動畫(方式同單個動畫建立方式,此處不作過多描述)
// 子動畫1:旋轉動畫
Animation rotate = new RotateAnimation(, , Animation.RELATIVE_TO_SELF, f, Animation.RELATIVE_TO_SELF, f);
rotate.setDuration();
rotate.setRepeatMode(Animation.RESTART);
rotate.setRepeatCount(Animation.INFINITE);
rotate.setStartOffset();
// 子動畫2:平移動畫
Animation translate = new TranslateAnimation(, , , );
translate.setDuration();
rotate.setStartOffset();
// 子動畫3:透明度動畫
Animation alpha = new AlphaAnimation(, );
alpha.setDuration();
alpha.setStartOffset();
// 步驟4:将建立的子動畫添加到組合動畫裡
setAnimation.addAnimation(rotate);
setAnimation.addAnimation(translate);
setAnimation.addAnimation(alpha);
// 步驟5:播放動畫
mIvImage.startAnimation(setAnimation);
}
}
頁面切換動畫
進入其他頁面的動畫:
startActivity(new Intent(this, ChangeActivity.class));
/*
enterAnim:從Activity a跳轉到Activity b,進入b時的動畫效果資源ID
exitAnim:從Activity a跳轉到Activity b,離開a時的動畫效果資源Id
overridePendingTransition()必須要在startActivity(intent)後被調用才能生效
*/
this.overridePendingTransition(R.anim.anim_bottom_in, );
退出頁面的動畫:
@Override
public void onBackPressed() {
super.onBackPressed();
this.overridePendingTransition(, R.anim.anim_bottom_out);
}
建立xml檔案,, 檔案路徑
res/anim/anim_bottom_in.xml
和
res/anim/anim_bottom_out.xml
anim_bottom_in.xml:
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate
android:duration="600"
android:fromYDelta="100%"
android:toYDelta="0"/>
</set>
anim_bottom_out.xml:
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate
android:duration="600"
android:fromYDelta="0"
android:toYDelta="100%" />
</set>
結果展示:
動畫監聽
通過在 Java 代碼裡setAnimationListener()方法設定
translateAnimation.setAnimationListener(new Animation.AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {
//動畫開始時執行
}
@Override
public void onAnimationEnd(Animation animation) {
//動畫取消時執行
}
@Override
public void onAnimationRepeat(Animation animation) {
//動畫重複時執行
}
});
項目源碼