1.android系統中動畫框架分爲:傳統的view動畫框架和Android 3.0推出的屬性動畫框架。
View動畫框架又包括Tween補間動畫和Frame逐幀動畫
2.補間動畫 TweenAnimation : 分成AlphaAnimation, RotateAnimation, ScaleAnimation, TranslateAnimation
(1)AlphaAnimation
創建alpha文件,在這個目錄下src/main/res/anim/alpha.xml
<?xml version="1.0" encoding="utf-8"?>
<alpha xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="2000"
android:fromAlpha="1.0"
android:toAlpha="0.0"/>
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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"
tools:context=".MainActivity">
<LinearLayout
android:id="@+id/ll_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<Button
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="透明"
android:onClick="alphaClick"/>
<Button
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="縮放"
android:onClick="scaleClick" />
<Button
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:maxLines="1"
android:text="位移"
android:onClick="translateClick"/>
<Button
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="旋轉"
android:onClick="rotateClick"/>
<Button
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="還原"
android:onClick="reset"/>
</LinearLayout>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/ll_container"
android:id="@+id/image"
android:src="@mipmap/ic_launcher"/>
MainActivity.java
public class MainActivity extends AppCompatActivity {
private ImageView imageView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
imageView = findViewById(R.id.image);
}
@Override
protected void onDestroy() {
super.onDestroy();
}
public void alphaClick(View view){
//加載xml中的動畫
Animation alphaAnimation = AnimationUtils.loadAnimation(this,R.anim.alpha);
//動畫運行完成保持結束的狀態
alphaAnimation.setFillAfter(true);
imageView.startAnimation(alphaAnimation);
}
public void reset(View view){
//移除所有動畫
imageView.clearAnimation();
}
}
(2)ScaleAnimation 接着上面的佈局和java文件
創建src/main/res/anim/scale.xml
<?xml version="1.0" encoding="utf-8"?>
<scale xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="5000"
android:fromXScale="1.0"
android:fromYScale="1.0"
android:interpolator="@android:anim/accelerate_interpolator"
android:pivotX="50%"
android:pivotY="50%"
android:toXScale="0.5"
android:toYScale="0.5"/>
MainActivity.java中加入如下方法:
public void scaleClick(View view){
Animation scaleAnimation = AnimationUtils.loadAnimation(this,R.anim.scale);
scaleAnimation.setFillAfter(true);
imageView.startAnimation(scaleAnimation);
}
(3)TranslateAnimation 接着上面的佈局和java文件
創建src/main/res/anim/translate.xml
<?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="2000"
android:fromXDelta="20"
android:fromYDelta="20"
android:toXDelta="100"
android:toYDelta="100">
</translate>
MainActivity.java中加入如下方法:
public void translateClick(View view){
Animation animation = AnimationUtils.loadAnimation(this,R.anim.translate);
animation.setFillAfter(true);
imageView.startAnimation(animation);
}
(4)RotateAnimation 接着上面的佈局和java文件
創建src/main/res/anim/rotate.xml
<?xml version="1.0" encoding="utf-8"?>
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="1000"
android:fromDegrees="0"
android:pivotY="50%"
android:pivotX="50%"
android:toDegrees="+360">
</rotate>
MainActivity.java中加入如下方法:
public void rotateClick(View view){
Animation animation = AnimationUtils.loadAnimation(this,R.anim.rotate);
animation.setFillAfter(true);
imageView.startAnimation(animation);
}
3.逐幀動畫
一系列圖片按照一定的順序展現的過程,逐幀動畫可以定義在xml中,也可以定義在Java中。
如果定義在xml中,可以放置在res/anim或res/drawable目錄中(filename.xml),文件名可以作爲資源id在代碼中引用;如果完全由編碼實現,需要使用到AnimationDrawable對象。
(1)xml定義格式
<?xml version="1.0" encoding="utf-8"?>
<animation-list xmlns:android="http://schemas.android.com/apk/res/android" //animation-list根元素
android:oneshot=["false"|"true"]> //true表示動畫只執行一次
<item android:drawable="@[package:]drawable/drawable_resource_name"
android:duration="integer"/> //持續時間,整數 ms
</animation-list>
示例如下:
首先在drawable下創建frame.xml文件
<?xml version="1.0" encoding="utf-8"?>
<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
android:oneshot="false">
<item android:drawable="@drawable/f1" android:duration="500"/>
<item android:drawable="@drawable/f2" android:duration="500"/>
<item android:drawable="@drawable/f3" android:duration="500"/>
<item android:drawable="@drawable/f4" android:duration="500"/>
<item android:drawable="@drawable/f5" android:duration="500"/>
</animation-list>
res/layout/activity_main.xml文件
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<ImageView
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:id="@+id/image"/>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="stopFrame"
android:onClick="stopFrame"/>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="runFrame"
android:onClick="runFrame"/>
</LinearLayout>
FrameActivity.java
public class FrameActivity extends AppCompatActivity {
private ImageView image;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_frame);
image = findViewById(R.id.image);
image.setImageResource(R.drawable.frame);
}
public void runFrame(View view){
//獲取image顯示的圖片,此時已被編譯成AnimationDrawable
AnimationDrawable anim = (AnimationDrawable) image.getDrawable();
anim.start(); //開始動畫
}
public void stopFrame(View view){
AnimationDrawable anim = (AnimationDrawable)image.getDrawable();
if (anim.isRunning()){ //如果正在運行,就停止
anim.stop();
}
}
}
注意 :oncreate()中不能調用AnimationDrawable的start()方法,以爲窗口對象還沒有完全初始化,AnimationDrawable不能完全追加到窗口window對象中。如果希望程序運行就自動播放幀動畫,需要把代碼放在onWindowFocusChanged()方法中,當activity展示給用戶時,onWindowFocusChanged就會被調用,此時實現動畫效果。
(2)純java代碼啓動幀動畫
public class FrameActivity extends AppCompatActivity {
private ImageView image;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_frame);
image = findViewById(R.id.image);
//將動畫資源文件設置爲ImageView顯示的圖片
// image.setImageResource(R.drawable.frame);
}
@Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
//完全編碼實現的動畫效果
AnimationDrawable anim = new AnimationDrawable();
for (int i =1; i<=5 ; i++){
//根據資源名稱和目錄獲取獲取R.java中對應的資源id
int id = getResources().getIdentifier("f"+i,"drawable",getPackageName());
//根據資源id獲取到drawable對象
Drawable drawable =getResources().getDrawable(id);
anim.addFrame(drawable,500);
}
anim.setOneShot(false);
image.setImageDrawable(anim);
anim.start();
}
}
4.屬性動畫
能實現所有view框架能實現的動畫效果和無法實現的動畫效果,也可以定義xml或者直接通過Java代碼實現。定義的xml文件放在res/animator文件夾下。
利用屬性動畫實現補間動畫中透明度,位移,旋轉,縮放的示例如下,佈局不變,java代碼如下:
public class MainActivity extends AppCompatActivity {
private ImageView imageView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
imageView = findViewById(R.id.image);
}
@Override
protected void onDestroy() {
super.onDestroy();
}
public void alphaClick(View view){
ObjectAnimator.ofFloat(imageView,"alpha",1,0,1)
.setDuration(2000).start();
}
public void reset(View view){
//移除所有動畫
// imageView.clearAnimation();
}
public void scaleClick(View view){
AnimatorSet animatorSet = new AnimatorSet();
imageView.setPivotX(imageView.getWidth()/2);
imageView.setPivotY(imageView.getHeight()/2);
animatorSet.playTogether(
ObjectAnimator.ofFloat(imageView,"scaleX",1,0,1)
.setDuration(5000),
ObjectAnimator.ofFloat(imageView,"scaleY",1,0,1)
.setDuration(5000)
);
animatorSet.start();
}
public void translateClick(View view){
AnimatorSet animatorSet = new AnimatorSet();
animatorSet.playTogether(
ObjectAnimator.ofFloat(imageView,"translationX",20,100,0)
.setDuration(2000),
ObjectAnimator.ofFloat(imageView,"translationY",20,100,0)
.setDuration(2000)
);
animatorSet.start();
}
public void rotateClick(View view){
imageView.setPivotX(imageView.getWidth()/2);
imageView.setPivotY(imageView.getHeight()/2);
ObjectAnimator.ofFloat(imageView,"rotation",0,360)
.setDuration(1000).start();
}
}