搜尋
首頁类库下载java类库初識android中的動畫

初識android中的動畫

Nov 05, 2016 am 10:31 AM

       動畫效果可大幅提升介面的互動效果,因此,動畫在行動開發的應用場景較為普遍。掌握基本的動畫效果在成熟的軟體開發中不可或缺。除此之外,使用者對於動畫的接受程度遠高於文字和圖片,利用動畫效果可以加深使用者對於產品的印象。因此本文給出安卓設計中幾種常見的動畫效果。

       基礎知識

       在介紹安卓中的動畫效果之前,請先介紹一下安卓中的圖片處理機制。圖片的特效包括圖形的縮放、鏡面、倒影、旋轉、平移等。圖片的特效處理方式是將原圖的圖形矩陣乘以特效矩陣,形成一個新的圖形矩陣來實現的。矩陣Matrix 類,維護了一個3*3 的矩陣去更改像素點的座標。 Android 手機的螢幕座標係以左上角為原點,由左向右為x軸正方向,由上至下為y軸正方向。第一行表示像素點的x 座標:x = 1*x + 0*y + 0*z,第二行表示像素點的y 座標:y = 0*x + 1*y + 0*z,第三行表示像素點的z 座標:z = 0*x + 0*y + 1*z。圖片的特效處理正是透過更改圖形矩陣的值來實現的,在android下Matrix這個類別幫我們封裝了矩陣的一些基本用法,所以我們可以直接使用即可。用程式碼編輯圖片,最好處理都是圖片在記憶體中的拷貝,不去處理原圖,因此需要用Bitmap創建一個與原圖大小一致,格式相同的空白位圖。

    操作照片的基本步驟:

      1. 建立一個空白的bitmap,寬高資訊與原圖儲存一致;

   

      4. 設置matrix矩陣;

      5. 對照著原圖在畫紙上面畫出一模一樣的樣子出來。

      以下分別給出圖片縮放、平移、旋轉、鏡面操作的程式碼。

/**
     * 图片缩放
     * 
     */
    private void zoom() {
        Bitmap srcBitmap = BitmapFactory.decodeFile("mnt/sdcard/b.jpg");
        iv_src.setImageBitmap(srcBitmap);
        Bitmap copyBitmap = Bitmap.createBitmap(srcBitmap.getWidth(), srcBitmap.getHeight(), srcBitmap.getConfig());
        Canvas canvas = new Canvas(copyBitmap);
        Paint paint = new Paint();
        paint.setColor(Color.BLACK);
        Matrix matrix = new Matrix();
        matrix.setScale(0.6f, 0.6f);
        canvas.drawBitmap(srcBitmap, matrix, paint);
        iv_dest.setImageBitmap(copyBitmap);
    }
    
    /**
     * 图片平移
     * 
     */
    public void translation(){
        Options ops = new Options();
        ops.inSampleSize = 4;   //等比放缩
        Bitmap srcBitmap = BitmapFactory.decodeFile("/mnt/sdcard/b.jpg",ops);
        iv_src.setImageBitmap(srcBitmap);
        Bitmap copyBitmap = Bitmap.createBitmap(srcBitmap.getWidth(), srcBitmap.getHeight(), srcBitmap.getConfig());
        Canvas canvas = new Canvas(copyBitmap);
        Paint paint = new Paint();
        paint.setColor(Color.BLACK);
        Matrix matrix = new Matrix();
        matrix.setTranslate(100, 100);
        canvas.drawBitmap(srcBitmap, matrix, paint);
        iv_dest.setImageBitmap(copyBitmap);
    }
    /**
     * 旋转
     * 
     */
    public void scole(){
        Bitmap srcBitmap = BitmapFactory.decodeFile("/mnt/sdcard/b.jpg");
        iv_src.setImageBitmap(srcBitmap); 
        Bitmap copyBitmap = Bitmap.createBitmap(srcBitmap.getWidth(), srcBitmap.getHeight(), srcBitmap.getConfig());
        Canvas canvas = new Canvas(copyBitmap);
        Paint paint = new Paint();
        paint.setColor(Color.BLACK);
        Matrix matrix = new Matrix();
        matrix.setRotate(180, srcBitmap.getWidth()/2, srcBitmap.getHeight()/2);//绕原点旋转
        canvas.drawBitmap(srcBitmap, matrix, paint);
        iv_dest.setImageBitmap(copyBitmap);
    }
    /**
     * 镜面特效/倒影特效
     * 原理一样,一个关于x轴旋转,一个关于y轴旋转
     */
    public void mirror(){
        Bitmap srcBitmap = BitmapFactory.decodeFile("/mnt/sdcard/b.jpg");
        iv_src.setImageBitmap(srcBitmap);
        Bitmap copyBitmap = Bitmap.createBitmap(srcBitmap.getWidth(), srcBitmap.getHeight(), srcBitmap.getConfig());
        Canvas canvas = new Canvas(copyBitmap);
        Paint paint = new Paint();
        paint.setColor(Color.BLACK);
        Matrix matrix = new Matrix();
        matrix.setScale(-1, 1);
        matrix.postTranslate(srcBitmap.getWidth(), 0);
        canvas.drawBitmap(srcBitmap, matrix, paint);
        iv_dest.setImageBitmap(copyBitmap);
    }

       接下來進入進入今天的主題。安卓下的動畫分為三種: 幀動畫、View動畫(補間動畫)、屬性動畫。以下分別介紹這三種動畫。 

       影格動畫:

       畫面動畫是這三種動畫中最常見的一種,指的是一格一格播放的動畫。更直白的講就是快速切換圖片的效果。透過animation-list來實現,創建一個Drawable 序列,這些Drawable 可以按照指定的時間間隔一個一個的顯示,也就是順序播放事先做好的圖像。

       幀動畫使用的基本步驟:

         1 . 建立影格動畫每格需要的圖片, 放到對應的d xml 文件,根節點選擇animation-list。 oneshot屬性表示幀動畫的自動執行。 如果為true,表示動畫只播放一次停止在最後一格上,如果設定為false表示動畫循環播放。

         3. 在JAVA代碼中開啟動畫。設定為 View 的 Background 或 ImageView 的 src,然後取得到控制項的 AnimationDrawable 對象,透過 AnimationDrawable.start() 方法啟動動畫

         下方以火箭的發射為例示範動畫。

          xml檔案中的程式碼:

<?xml version="1.0" encoding="utf-8"?><animation-list xmlns:android="http://schemas.android.com/apk/res/android" >
   <item android:drawable="@drawable/desktop_rocket_launch_1" android:duration="200" />
   <item android:drawable="@drawable/desktop_rocket_launch_2" android:duration="200" /></animation-list>

        Java程式碼的實作:

        iv = new ImageView(this);        
        //开启帧动画   rocket为上述xml文件       
         iv.setBackgroundResource(R.drawable.rocket);
        AnimationDrawable ad = (AnimationDrawable) iv.getBackground();
        ad.start();
Android3.0以上的系統也就是說運行在API-11 以上的系統。屬性動畫會改變目前的視圖所在的位置,透過動態改變控制項的寬、高、座標等屬性而產生的動畫效果。

     透過控制控制的屬性來實現動畫效果,而屬性動畫比補間動畫更有彈性、更強大的更多。要注意的是屬性動畫內部其實並沒有區分位移、縮放、透明、旋轉等動畫,其核心思想只是修改一個控制項的屬性,我們可以透過修改不同的屬性來實現補間動畫的4 種效果而已。

     属性动画跟补间动画比,属性动画是真正改变了控件的属性,会改变当前的视图所在的位置,因此当控件的位置改变后只要点击到了控件“身上”就能触发onClick 事件。而补间动画则并没用改变控件的真实属性,因此不管属性动画执行后将控件移动到了哪个位置,只能通过点击该控件的原始位置才能触发onClick 事件。

     通过xml 文件实现属性动画步骤:

     1. 在res 下创建属性动画文件。在res 目录下创建animator 文件夹,然后创建一个objectAnimator 资源文件。资源名称自定义即可。

     2. 编写属性动画文件。指定属性值。

     3. 编写代码使用属性动画文件。通过AnimatorInflater加载图片资源,指定要显示动画的控件,并开启动画。

     属性动画可以通过xml文件实现,但通常属性动画是通过JAVA代码实现。这里仅给出用xml文件实现淡化动画的案例,其他案例均以JAVA代码的方式实现。

     JAVA代码的方式实现属性动画。

public class MainActivity extends Activity {
    private ImageView iv;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        iv = (ImageView) findViewById(R.id.iv);
    }
    /**
     * 淡化动画
     * @param view
     */
    public void alpha(View view) {
        ObjectAnimator oa = ObjectAnimator.ofFloat(iv, "alpha", new float[] {
                0.0f, 0.2f, 0.4f, 0.6f, 0.8f, 1.0f });
        oa.setDuration(3000);
        oa.setRepeatCount(ObjectAnimator.INFINITE);
        oa.setRepeatMode(ObjectAnimator.REVERSE);
        oa.start();
    }
    /**
     * 平移动画
     * @param view
     */
    public void trans(View view) {
        ObjectAnimator oa = ObjectAnimator.ofFloat(iv, "translationX",
                new float[] { 10f, 20f, 30f, 40f, 60f, 80f });
        oa.setDuration(3000);
        oa.setRepeatCount(ObjectAnimator.INFINITE);
        oa.setRepeatMode(ObjectAnimator.REVERSE);
        oa.start();
    }
    /**
     * 缩放动画
     */
    public void scale(View view) {
        ObjectAnimator oa = ObjectAnimator.ofFloat(iv, "scaleX", new float[] {
                1f, 2f, 3f, 4f, 5f, 6f });
        oa.setDuration(3000);
        oa.setRepeatCount(ObjectAnimator.INFINITE);
        oa.setRepeatMode(ObjectAnimator.REVERSE);
        oa.start();
    }

    /**
     * 旋转动画
     */
    public void rotate(View view) {
        ObjectAnimator oa = ObjectAnimator.ofFloat(iv, "rotationY",
                new float[] { 90f, 180f, 270f, 360f });
        oa.setDuration(3000);
        oa.setRepeatCount(ObjectAnimator.INFINITE);
        oa.setRepeatMode(ObjectAnimator.REVERSE);
        oa.start();
    }

    /**
     * 水平平移 + 竖直平移
     */
    public void set(View view) {
        AnimatorSet set = new AnimatorSet();
        ObjectAnimator oa = ObjectAnimator.ofFloat(iv, "translationX",
                new float[] { 10f, 20f, 30f, 40f, 60f, 80f });
        oa.setDuration(3000);
        ObjectAnimator oa2 = ObjectAnimator.ofFloat(iv, "translationY",
                new float[] { -10f, -20f, -30f, -40f, -60f, -80f });
        oa2.setDuration(3000);
        set.playTogether(oa, oa2);
        set.start();
    }

}

       xml文件实现淡化效果:

<?xml version="1.0" encoding="utf-8"?>
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="3000"
    android:propertyName="alpha"
    android:repeatCount="3"
    android:repeatMode="reverse"
    android:valueFrom="0.0"
    android:valueTo="1.0" >

</objectAnimator>

        然后在java代码中实现这样一段代码: 

      public void alpha(View view) {
          Animator animator = AnimatorInflater.loadAnimator(this,
                  R.animator.alpha);
          animator.setTarget(iv);
          animator.start();
      }

      View动画:

      渐变动画也叫补间动画。补间动画通过对View 的内容进行一系列的图形变换(包括平移、缩放、旋转、改变透明度)来实现动画效果。动画效果的定义可以采用XML 文件来做也可以采用java 代码来做。

      使用XML 文件实现View动画的步骤:

         1.  在res 目录下创建anim 文件夹。

         2.  在anim 文件夹中创建xml文件,文件名可以自定义。

         3.  编辑xml文件。定义不同的标签,表示不同的动画效果。alpha表示淡化,

         4.  添加Java 逻辑代码,使用AnimationUtils 工具类加载xml 文件,获取Animation 对象,调用startAnimation 让ImageView 执行此动画。

     View动画中常用属性的含义:

          duration 动画时长

          fromAlpha 起始透明度,1 为完全不透明,0 为完全透明

          repeatCount 重复次数,INFINITE表示无限重复

          toAlpha 目标透明度

          repeatMode 重复模式,restart 为重新开始,reverse表示来回播放

     渐变动画在代码中使用的是AlphaAnimation 类来定义,在XML 文件中使用节点来定义。旋转动画在代码中使用的是RotateAnimation 类来定义,在XML 文件中使用节点来定义。伸缩动画在代码中使用的是ScaleAnimation 类来定义,在XML 文件中使用节点来定义。平移动画在代码中使用的是TranslateAnimation 类来定义,在XML 文件中使用节点来定义。Android 提供了AnimationSet 动画集合用于将多种补间动画联合起来一起使用,这样就能实现更多复杂的动画效果。动画集合既可以使用AnimationSet 类来定义也可以在XML 文件中使用节点来定义。任何复杂的动画均是通过简单的动画集合在一起的。

     使用编码方式同样可以实现view动画,直接创建相应的动画对象,然后添加相应的属。代使用编码方式实现view动画跟用XML 文件实现View动画其实是一模一样的,无非就是在JAVA代码中设定相关的属性罢了。

     使用XML 文件实现View动画的代码:  

     1 .   在anim文件夹下新建下列文件:

<!-- alpha_demo.xml 文件夹下 -->
<?xml version="1.0" encoding="utf-8"?>
<alpha xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="2000"
    android:fromAlpha="0.0"
    android:repeatCount="infinite"
    android:repeatMode="reverse"
    android:toAlpha="1.0" >
</alpha>

<!-- rotate_demo.xml 文件夹下 -->
<?xml version="1.0" encoding="utf-8"?>
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="2000"
    android:fromDegrees="0"
    android:pivotX="50%"
    android:pivotY="50%"
    android:repeatCount="2"
    android:repeatMode="reverse"
    android:toDegrees="360" >
</rotate>

<!-- scale_demo.xml 文件夹下 -->
<?xml version="1.0" encoding="utf-8"?>
<scale xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="2000"
    android:fromXScale="20%"
    android:fromYScale="20%"
    android:pivotX="50%"
    android:pivotY="50%"
    android:repeatCount="2"
    android:repeatMode="reverse"
    android:toXScale="200%"
    android:toYScale="200%" >
</scale>

<!-- set_demo.xml 文件夹下   -->
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:fillAfter="true" >

    <rotate
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:duration="2000"
        android:fromDegrees="0"
        android:pivotX="50%"
        android:pivotY="50%"
        android:repeatCount="2"
        android:repeatMode="reverse"
        android:toDegrees="360" >
    </rotate>

    <scale
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:duration="2000"
        android:fromXScale="20%"
        android:fromYScale="20%"
        android:pivotX="50%"
        android:pivotY="50%"
        android:repeatCount="2"
        android:repeatMode="reverse"
        android:toXScale="200%"
        android:toYScale="200%" >
    </scale>

</set>

<!-- trans_demo.xml 文件夹下 -->
<?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="2000"
    android:fromXDelta="0"
    android:fromYDelta="0"
    android:repeatCount="2"
    android:repeatMode="reverse"
    android:toXDelta="100%"
    android:toYDelta="100%" >
</translate>

      2 .   在java代码中实现下列逻辑:

import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.ImageView;

public class MainActivity extends Activity {
    private ImageView iv;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        iv = (ImageView) findViewById(R.id.iv);
    }
    /**
     * 淡化动画
     * @param view
     */
     public void alpha(View view){
         Animation aa = AnimationUtils.loadAnimation(this, R.anim.alpha_demo);
         iv.startAnimation(aa);
     }

     /**
      * 平移动画
      * @param view
      */
     public void trans(View view){
         Animation ta = AnimationUtils.loadAnimation(this, R.anim.trans_demo);
         iv.startAnimation(ta);
     }
     /**
      * 缩放动画
      */
     public void scale(View view){
         Animation sa = AnimationUtils.loadAnimation(this, R.anim.scale_demo);
         iv.startAnimation(sa);
     }
     /**
      * 旋转动画
      */
     public void rotate(View view){
         Animation ra = AnimationUtils.loadAnimation(this, R.anim.rotate_demo);
         iv.startAnimation(ra);
     }
     /**
      * 旋转 + 放缩
      */
     public void set(View view){
         Animation set = AnimationUtils.loadAnimation(this, R.anim.set_demo);
         iv.startAnimation(set);
     }
}

       使用java代码实现View动画的代码

import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.view.View;
import android.view.animation.AlphaAnimation;
import android.view.animation.Animation;
import android.view.animation.AnimationSet;
import android.view.animation.AnimationUtils;
import android.view.animation.RotateAnimation;
import android.view.animation.ScaleAnimation;
import android.view.animation.TranslateAnimation;
import android.widget.ImageView;

public class MainActivity extends Activity {
     private ImageView iv;

     @Override
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
         setContentView(R.layout.activity_main);
         iv = (ImageView) findViewById(R.id.iv);
     }
     /**
      * 渐变动画
      * @param view
      */
     public void alpha(View view) {
         AlphaAnimation aa = new AlphaAnimation(0.0f, 1.0f);
         aa.setDuration(2000);
         aa.setRepeatCount(Animation.INFINITE);
         aa.setRepeatMode(Animation.REVERSE);
         iv.startAnimation(aa);
     }
     /**
      * 平移动画
      * @param view
      */
     public void trans(View view) {
         TranslateAnimation ta = new TranslateAnimation(
                 Animation.RELATIVE_TO_SELF, 0, Animation.RELATIVE_TO_SELF, 1f,
                 Animation.RELATIVE_TO_SELF, 0, Animation.RELATIVE_TO_SELF, 1f);
         ta.setDuration(2000);
         ta.setRepeatCount(Animation.INFINITE);
         ta.setRepeatMode(Animation.REVERSE);
         iv.startAnimation(ta);
     }
     /**
      * 缩放动画
      */
     public void scale(View view) {
         ScaleAnimation sa = new ScaleAnimation(0.2f, 2.0f, 0.2f, 2.0f,
                 Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF,
                 0.5f);
         sa.setDuration(2000);
         sa.setRepeatCount(Animation.INFINITE);
         sa.setRepeatMode(Animation.REVERSE);
         iv.startAnimation(sa);
     }

     /**
      * 旋转动画
      */
     public void rotate(View view) {
         RotateAnimation ra = new RotateAnimation(0, 360,
                 Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF,
                 0.5f);
         ra.setDuration(2000);
         ra.setRepeatCount(Animation.INFINITE);
         ra.setRepeatMode(Animation.REVERSE);
         iv.startAnimation(ra);
     }

     /**
      *  旋转 + 平移 + 放缩
      *  AnimationSet添加各个动画
      */
     public void set(View view) {
         AnimationSet set = new AnimationSet(false);
         RotateAnimation ra = new RotateAnimation(0, 360,
                 Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF,
                 0.5f);
         ra.setDuration(2000);
         ra.setRepeatCount(Animation.INFINITE);
         ra.setRepeatMode(Animation.REVERSE);
         ScaleAnimation sa = new ScaleAnimation(0.2f, 2.0f, 0.2f, 2.0f,
                 Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF,
                 0.5f);
         sa.setDuration(2000);
         sa.setRepeatCount(Animation.INFINITE);
         sa.setRepeatMode(Animation.REVERSE);
         TranslateAnimation ta = new TranslateAnimation(
                 Animation.RELATIVE_TO_SELF, 0, Animation.RELATIVE_TO_SELF, 1f,
                 Animation.RELATIVE_TO_SELF, 0, Animation.RELATIVE_TO_SELF, 1f);
         ta.setDuration(2000);
         ta.setRepeatCount(Animation.INFINITE);
         ta.setRepeatMode(Animation.REVERSE);
         set.addAnimation(ta);
         set.addAnimation(sa);
         set.addAnimation(ra);
         iv.startAnimation(set);
     }
}

 自此Android下的三种动画全部讲解完毕。

陳述
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

Safe Exam Browser

Safe Exam Browser

Safe Exam Browser是一個安全的瀏覽器環境,安全地進行線上考試。該軟體將任何電腦變成一個安全的工作站。它控制對任何實用工具的訪問,並防止學生使用未經授權的資源。

PhpStorm Mac 版本

PhpStorm Mac 版本

最新(2018.2.1 )專業的PHP整合開發工具

MinGW - Minimalist GNU for Windows

MinGW - Minimalist GNU for Windows

這個專案正在遷移到osdn.net/projects/mingw的過程中,你可以繼續在那裡關注我們。 MinGW:GNU編譯器集合(GCC)的本機Windows移植版本,可自由分發的導入函式庫和用於建置本機Windows應用程式的頭檔;包括對MSVC執行時間的擴展,以支援C99功能。 MinGW的所有軟體都可以在64位元Windows平台上運作。

MantisBT

MantisBT

Mantis是一個易於部署的基於Web的缺陷追蹤工具,用於幫助產品缺陷追蹤。它需要PHP、MySQL和一個Web伺服器。請查看我們的演示和託管服務。

VSCode Windows 64位元 下載

VSCode Windows 64位元 下載

微軟推出的免費、功能強大的一款IDE編輯器