你的位置:首页 > 操作系统

[操作系统]安卓实现图片闪烁效果动画


  大家在使用APP的时候,有的APP在点击语音搜索界面后,会出现一个小话筒,小话筒会类似雷达似得在闪烁,表示正在倾听你说话的内容(这个大家可以参照微软的必应APP),那么问题来了,这种动画效果是如何实现的呢?其实实现这种动画效果有很多种方法,最常见的是两种:第一种就是插入n张图片进行切换已达到如此目的,第二种就是通过改变一张图片的透明度来达到闪烁的效果。下面就分别讲一下通过这两种方法如何实现。

第一种:通过n张图片之间切换实现动画效果

  这种方法的原理很简单,利用handler的延时机制在子线程中完成图片切换,再在主线程展示。

  1、首先我们要先写一个线程池,在使用的时候方便调用。

 1 package com.jereh.musicapplication.threadpool; 2  3 import java.util.concurrent.ExecutorService; 4 import java.util.concurrent.Executors; 5 import java.util.concurrent.ScheduledExecutorService; 6  7 /** 8  * Created by zhangdi on 2016/9/1. 9  * 这是一个线程池的工具类,在用到线程的时候可以直接类名加方法名使用10 */11 public class ThreadPoolManager {12   /** 线程执行器 **/13   private static ExecutorService executorService = null;14   /** 固定5个线程 **/15   private static int nThreads = 5;16   /** 单例 **/17   private static ThreadPoolManager taskExecutorPool = null;18 19 20 21   /** 初始化线程池 **/22   static {23     taskExecutorPool = new ThreadPoolManager(nThreads * getNumCores());24   }25 26   /** 构造函数 **/27   private ThreadPoolManager(int threads) {28     //executorService = Executors.newFixedThreadPool(threads);29     executorService = Executors.newScheduledThreadPool(threads);30   }31 32   /**33    * 取得单例34    *35    * @return36   */37   public static ThreadPoolManager getInstance() {38     return taskExecutorPool;39   }40 41   /**42    * 取得线程执行器43    *44    * @return45   */46   public ExecutorService getExecutorService() {47     return executorService;48   }49 50   /**51    * 取得周期性线程执行器52    * @return53   */54   public ScheduledExecutorService getScheduledExcutorService(){55     return (ScheduledExecutorService)executorService;56   }57 58   /**59    * 获得手机cup个数60    * @return61   */62   public static int getNumCores() {63     int threadCount = Runtime.getRuntime().availableProcessors();64     return threadCount;65   }66 67 }

  2、下一步就是在

1 <FrameLayout2     android:layout_width="match_parent"3     android:layout_height="match_parent"4     android:id="@+id/fl"/>

  3、然后就是在java代码中编辑切换图片了:

 1 package com.jereh.musicapplication; 2  3 import android.graphics.drawable.Drawable; 4 import android.os.Message; 5 import android.support.v7.app.AppCompatActivity; 6 import android.os.Bundle; 7 import android.widget.FrameLayout; 8  9 import com.jereh.musicapplication.threadpool.ThreadPoolManager;10 11 import java.util.Timer;12 import java.util.TimerTask;13 import java.util.concurrent.TimeUnit;14 15 public class FrameActivity extends AppCompatActivity {16 17   private Timer timer;18   FrameLayout frameLayout;19   Drawable drawable;20   android.os.Handler handler = new android.os.Handler(){21     int i = 0;22     @Override23     public void handleMessage(Message msg) {24       if (msg.what==1){25         i++;26         move(i%4);27       }28       super.handleMessage(msg);29     }30   };31   void move(int i){32     drawable = getResources().getDrawable(R.mipmap.ic_launcher,null);33     Drawable drawable1 = getResources().getDrawable(R.mipmap.dd1,null);34     Drawable drawable2 = getResources().getDrawable(R.mipmap.dd2,null);35     Drawable drawable3 = getResources().getDrawable(R.mipmap.dd3,null);36     switch (i){37       case 0:38         frameLayout.setForeground(drawable);39         break;40       case 1:41         frameLayout.setForeground(drawable1);42         break;43       case 2:44         frameLayout.setForeground(drawable2);45         break;46       case 3:47         frameLayout.setForeground(drawable3);48         break;49     }50   }51   @Override52   protected void onCreate(Bundle savedInstanceState) {53     super.onCreate(savedInstanceState);54     setContentView(R.layout.activity_frame);55   frameLayout = (FrameLayout)findViewById(R.id.fl);56   timer = new Timer();57 //  timer.schedule(new TimerTask() {58 //    @Override59 //    public void run() {60 //      handler.sendEmptyMessage(1);61 //    }62 //  },0,500);//第二个参数是隔多少秒之后开始显示,第三个是隔多久显示下一个63 64     ThreadPoolManager65         .getInstance()66         .getScheduledExcutorService()67         .scheduleAtFixedRate(new Runnable() {68           @Override69           public void run() {70             handler.sendEmptyMessage(1);71           }72         },0,500, TimeUnit.MILLISECONDS);//第二个参数是隔多少秒之后开始显示,第三个是隔多久显示下一个73 }74 75 76   @Override77   protected void onDestroy() {78     timer.cancel();79     super.onDestroy();80 81   }82 }

这里我写了两种方式,第一种是用Timer类来实现,后来发现使用自定义的线程池更好,大家如果不想在定义一个线程池的话,可以直接使用Timer类来实现同样的效果,至此使用第一种级n张图片切换实现动画效果的代码就完成了。这种方式有一个弊端就是得需要n张图片,那么要是只有单张图片又该怎么办呢,那么就可以使用下面这种方法了。

第二种:通过改变图片透明度实现动画效果

  1、首先我们先封装两个动画方法,第一个是从不透明到完全透明,第二个是完全透明到不透明

 1 /** 2    * 透明效果 3    * @return 4   */ 5   public Animation getAlphaAnimationIn() { 6     //实例化 AlphaAnimation 主要是改变透明度 7     //透明度 从 1-不透明 0-完全透明 8     Animation animation = new AlphaAnimation(1.0f, 0); 9     //设置动画插值器 被用来修饰动画效果,定义动画的变化率10     animation.setInterpolator(new DecelerateInterpolator());11     //设置动画执行时间12     animation.setDuration(2000);13     return animation;14   }15   public Animation getAlphaAnimationOut() {16     //实例化 AlphaAnimation 主要是改变透明度17     //透明度 从 1-不透明 0-完全透明18     Animation animation = new AlphaAnimation(0, 1.0f);19     //设置动画插值器 被用来修饰动画效果,定义动画的变化率20     animation.setInterpolator(new DecelerateInterpolator());21     //设置动画执行时间22     animation.setDuration(2000);23     return animation;24   }

  2、分别给这两个方法设置监听,即第一个动画完成立刻执行第二个动画,第二个动画完成在立刻执行第一个动画以实现动画循环播放的效果

 1 voiceState1.setAnimation(animationIn); 2     voiceState1.setAnimation(animationOut); 3     /** 4      * 监听动画实现动画间的切换 5     */ 6     animationOut.setAnimationListener(new Animation.AnimationListener() { 7       @Override 8       public void onAnimationStart(Animation animation) { 9 10       }11 12       @Override13       public void onAnimationEnd(Animation animation) {14         voiceState1.startAnimation(animationIn);15       }16 17       @Override18       public void onAnimationRepeat(Animation animation) {19 20       }21     });22     animationIn.setAnimationListener(new Animation.AnimationListener() {23       @Override24       public void onAnimationStart(Animation animation) {25 26       }27 28       @Override29       public void onAnimationEnd(Animation animation) {30         voiceState1.startAnimation(animationOut);31       }32 33       @Override34       public void onAnimationRepeat(Animation animation) {35 36       }37     });

至此使用一张图片通过改变其透明度实现闪烁效果就完成了。

这两种方法在实现动画闪烁效果方面都很实用,希望能给大家的学习有所帮助,如果您感觉这篇文章还不错,就给推荐一下吧,若是哪个地方感觉笔者写的不好,也希望大家能够评论指正,谢谢!