初識android中的動畫

高洛峰
發布: 2016-11-05 10:31:02
原創
1526 人瀏覽過

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

       基礎知識

       在介紹安卓中的動畫效果之前,請先介紹一下安卓中的圖片處理機制。圖片的特效包括圖形的縮放、鏡面、倒影、旋轉、平移等。圖片的特效處理方式是將原圖的圖形矩陣乘以特效矩陣,形成一個新的圖形矩陣來實現的。矩陣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下的三种动画全部讲解完毕。

來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板
關於我們 免責聲明 Sitemap
PHP中文網:公益線上PHP培訓,幫助PHP學習者快速成長!