本文目錄
補間動畫概述和分類
在Android動畫中,補間動畫一共可以分成四類即透明度動畫、縮放動畫、旋轉動畫、位移動畫。
其實現方法可以通過xml來配置,也可以通過代碼來實現。
各類補間動畫實現
xml實現補間動畫
用xml
實現補間動畫,需要將xml放到res
下的anim
目錄,Android工程默認是沒有anim
文件夾的在讀文件前我們先把anim
文件夾以及文件建好
- 點中工程的
res
目錄 右鍵New
->Directory
-> 彈窗中輸入anim
- 點中剛剛新建的
anim
目錄 右鍵New
->Animation Resource File
- 創建好了以後輸入如下的佈局文件代碼
透明度動畫-AlphaAnimation
<?xml version="1.0" encoding="utf-8"?>
<alpha xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@android:anim/accelerate_decelerate_interpolator"
android:fromAlpha="1.0"
android:toAlpha="0.1"
android:duration="2000"/>
屬性值 | 含義 |
---|---|
fromAlpha | 起始透明度(透明度的範圍爲:0-1,完全透明-完全不透明) |
toAlpha | 結束透明度 |
duration | 持續時間(毫秒) |
縮放動畫-ScaleAnimation
<?xml version="1.0" encoding="utf-8"?>
<scale xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@android:anim/accelerate_interpolator"
android:fromXScale="0.2"
android:toXScale="1.5"
android:fromYScale="0.2"
android:toYScale="1.5"
android:pivotX="50%"
android:pivotY="50%"
android:duration="2000"/>
屬性值 | 含義 |
---|---|
fromXScale | 沿着X軸縮放的起始比例 |
fromYScale | 沿着X軸縮放的起始比例 |
toXScale | 沿着X軸縮放的結束比例 |
toYScale | 沿着Y軸縮放的結束比例 |
pivotX | 縮放的中軸點X座標,即距離自身左邊緣的位置,比如50%就是以圖像的 中心爲中軸點 |
pivotY | 縮放的中軸點Y座標 |
duration | 持續時間 |
位移動畫-TranslateAnimation
<?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@android:anim/accelerate_decelerate_interpolator"
android:fromXDelta="0"
android:toXDelta="320"
android:fromYDelta="0"
android:toYDelta="0"
android:duration="2000"/>
屬性值 | 含義 |
---|---|
fromXDelta | 動畫起始位置的X座標 |
fromYDelta | 動畫起始位置的Y座標 |
toXDelta | 動畫結束位置的X座標 |
toYDelta | 動畫結束位置的Y座標 |
duration | 持續時間 |
旋轉動畫-RotateAnimation
<?xml version="1.0" encoding="utf-8"?>
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@android:anim/accelerate_decelerate_interpolator"
android:fromDegrees="0"
android:toDegrees="360"
android:duration="1000"
android:repeatCount="1"
android:repeatMode="reverse"/>
屬性值 | 含義 |
---|---|
fromDegrees/toDegrees | 旋轉的起始/結束角度 |
repeatCount | 旋轉的次數,默認值爲0,代表一次,假如是其他值,比如3,則旋轉4次 另外,值爲-1或者infinite時,表示動畫永不停止 |
repeatMode | 設置重複模式,默認restart,但只有當repeatCount大於0或者infinite或-1時 纔有效。還可以設置成reverse,表示偶數次顯示動畫時會做方向相反的運動 |
duration | 持續時間 |
動畫組合-AnimationSet
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@android:anim/decelerate_interpolator"
android:shareInterpolator="true" >
<scale
android:duration="2000"
android:fromXScale="0.2"
android:fromYScale="0.2"
android:pivotX="50%"
android:pivotY="50%"
android:toXScale="1.5"
android:toYScale="1.5" />
<rotate
android:duration="1000"
android:fromDegrees="0"
android:repeatCount="1"
android:repeatMode="reverse"
android:toDegrees="360" />
<translate
android:duration="2000"
android:fromXDelta="0"
android:fromYDelta="0"
android:toXDelta="320"
android:toYDelta="0" />
<alpha
android:duration="2000"
android:fromAlpha="1.0"
android:toAlpha="0.1" />
</set>
添加布局文件代碼
往activity_main.xml
中添加5個按鈕和一張圖片
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#F44336"
tools:context=".MainActivity">
<Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:text="透明度"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="@+id/button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:text="縮放"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/button" />
<Button
android:id="@+id/button3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:text="位移"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/button2" />
<Button
android:id="@+id/button4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:text="旋轉"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/button3" />
<Button
android:id="@+id/button5"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:text="組合"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/button4" />
<ImageView
android:id="@+id/image"
android:layout_width="100dp"
android:layout_height="100dp"
android:background="@drawable/animation_flower"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintHorizontal_bias="0.497"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@+id/button2"
app:layout_constraintVertical_bias="0.76" />
</androidx.constraintlayout.widget.ConstraintLayout>
MainActivity.java
中響應點擊事件
public class MainActivity extends AppCompatActivity {
Button mButton1;
Button mButton2;
Button mButton3;
Button mButton4;
Button mButton5;
Animation animation = null;
ImageView mImageView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mImageView = findViewById(R.id.image);
mButton1 = findViewById(R.id.button);
mButton1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Animation animation = AnimationUtils.loadAnimation(MainActivity.this,R.anim.anim_alpha);
mImageView.startAnimation(animation);
}
});
mButton2 = findViewById(R.id.button2);
mButton2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
animation = AnimationUtils.loadAnimation(MainActivity.this,R.anim.anim_scale);
mImageView.startAnimation(animation);
}
});
mButton3 = findViewById(R.id.button3);
mButton3.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
animation = AnimationUtils.loadAnimation(MainActivity.this,R.anim.anim_translate);
mImageView.startAnimation(animation);
}
});
mButton4 = findViewById(R.id.button4);
mButton4.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
animation = AnimationUtils.loadAnimation(MainActivity.this,R.anim.anim_rotate);
mImageView.startAnimation(animation);
}
});
mButton5 = findViewById(R.id.button5);
mButton5.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
animation = AnimationUtils.loadAnimation(MainActivity.this,R.anim.anim_set);
mImageView.startAnimation(animation);
}
});
}
}
代碼實現補間動畫
用代碼實現補間動畫我們主要是通過構造Animation animation = new AlphaAnimation();
拿到響應的引用以後去設置動畫的一些屬性。
這些動畫的公共方法如下:
animation.setDuration(2000);
animation.setFillAfter(true);
animation.setFillBefore(false);
animation.setRepeatCount(2);
animation.setRepeatMode(Animation.RESTART);
屬性值 | 含義 |
---|---|
setDuration(2000) | 動畫持續時間 |
setFillAfter(true) | 如果設置爲true,控件動畫結束時,將保持動畫最後時的狀態 |
setFillBefore(false) | 如果設置爲true,控件動畫結束時,還原到開始動畫前的狀態 |
setRepeatCount(2) | 持續時間如果設置爲true,控件動畫結束時,還原到開始動畫前的狀態 |
setRepeatMode(Animation.RESTART); | 重複類型,有reverse和restart兩個值,reverse表示倒序回放,restart表示重新放一遍,必須與repeatCount一起使用 |
透明度動畫(AlphaAnimation)
透明度動畫參數最多的構造方法如下:
//fromAlpha 動畫開始的透明度,從0.0 --1.0 ,0.0表示全透明,1.0表示完全不透明
//toAlpha 動畫結束時的透明度,也是從0.0 --1.0 ,0.0表示全透明,1.0表示完全不透明
public AlphaAnimation(float fromAlpha, float toAlpha) {
}
使用:
animation= new AlphaAnimation(0, 1);
animation.setDuration(2000);
mImageView.startAnimation(animation);
縮放動畫(ScaleAnimation)
我們先來看下縮放動畫參數最多的構造方法
public ScaleAnimation(float fromX, float toX, float fromY, float toY,
int pivotXType, float pivotXValue, int pivotYType, float pivotYValue) {
}
構造方法參數的含義同前面的佈局文件一樣
屬性值 | 含義 |
---|---|
fromX | 沿着X軸縮放的起始比例 |
fromY | 沿着X軸縮放的起始比例 |
toX | 沿着X軸縮放的結束比例 |
toY | 沿着Y軸縮放的結束比例 |
pivotXValue | 縮放的中軸點X座標,即距離自身左邊緣的位置,比如50%就是以圖像的 中心爲中軸點 |
pivotXType | 有2種模式,RELATIVE_TO_SELF(相對於自身)和RELATIVE_TO_PARENT(相對於父佈局)pivotx,pivotY的值就應該是0-1的浮點數,分別對應xml中的%(自身)和%p(父佈局) |
pivotYValue | 縮放的中軸點Y座標,即距離自身左邊緣的位置,比如50%就是以圖像的 中心爲中軸點 |
pivotYType | 同pivotXType |
填入構造方法的參數
animation = new ScaleAnimation(0, 1.4f, 0, 1.4f,
ScaleAnimation.RELATIVE_TO_SELF,0.5f,ScaleAnimation.RELATIVE_TO_SELF,0.5f);
animation.setDuration(2000);
mImageView.startAnimation(animation);
效果如下:
位移動畫(TranslateAnimation)
參數最多的構造方法如下:
//fromXDelta 起始點X軸座標,可以是數值、百分數、百分數p 三種樣式,同scale
//fromYDelta 起始點Y軸從標,可以是數值、百分數、百分數p 三種樣式
//toXDelta 結束點X軸座標
//toYDelta 結束點Y軸座標
// fromYType、toYType同ScaleAnimation,
public TranslateAnimation(int fromXType, float fromXValue, int toXType,
float toXValue,int fromYType, float fromYValue, int toYType, float toYValue) {
}
使用:
animation= new TranslateAnimation(TranslateAnimation.RELATIVE_TO_SELF, 0, TranslateAnimation.RELATIVE_TO_SELF, 0.5f,
TranslateAnimation.RELATIVE_TO_SELF, 0, TranslateAnimation.RELATIVE_TO_SELF, 0.5f);
animation.setDuration(2000);
mImageView.startAnimation(animation);
效果如下:
旋轉動畫(RotateAnimation)
參數最多的構造方法如下:
public RotateAnimation(float fromDegrees, float toDegrees, int pivotXType,
float pivotXValue, int pivotYType, float pivotYValue) {
}
使用:
animation= new RotateAnimation(0, -720, RotateAnimation.RELATIVE_TO_SELF, 0.5f,
RotateAnimation.RELATIVE_TO_SELF, 0.5f);
animation.setDuration(2000);
mImageView.startAnimation(animation);
效果如下:
動畫組合(AnimationSet)
通過AnimationSet
可以將前面的四種動畫組合在一起,實現一些混合動畫效果
Animation rotateAnimation = new RotateAnimation(0, -720, RotateAnimation.RELATIVE_TO_SELF, 0.5f,
RotateAnimation.RELATIVE_TO_SELF, 0.5f);
rotateAnimation.setDuration(2000);
Animation translateAnimation = new TranslateAnimation(TranslateAnimation.RELATIVE_TO_PARENT, 0, TranslateAnimation.RELATIVE_TO_PARENT, 0.5f,
TranslateAnimation.RELATIVE_TO_PARENT, 0, TranslateAnimation.RELATIVE_TO_PARENT, 0.5f);
translateAnimation.setDuration(2000);
Animation scaleAnimation = new ScaleAnimation(0, 1.4f, 0, 1.4f, ScaleAnimation.RELATIVE_TO_SELF,
0.5f, ScaleAnimation.RELATIVE_TO_SELF, 0.5f);
scaleAnimation.setDuration(2000);
Animation alphaAnimation = new AlphaAnimation(0, 1);
alphaAnimation.setDuration(2000);
AnimationSet animationSet = new AnimationSet(true);
animationSet.addAnimation(rotateAnimation);
animationSet.addAnimation(translateAnimation);
animationSet.addAnimation(scaleAnimation);
animationSet.addAnimation(alphaAnimation);
animationSet.setDuration(4000);
animationSet.setFillAfter(true);
mImageView.startAnimation(animationSet);