動畫Animation

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();
 }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章