zoukankan      html  css  js  c++  java
  • 安卓实现图片闪烁效果动画

      大家在使用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      * @return
    36      */
    37     public static ThreadPoolManager getInstance() {
    38         return taskExecutorPool;
    39     }
    40 
    41     /**
    42      * 取得线程执行器
    43      *
    44      * @return
    45      */
    46     public ExecutorService getExecutorService() {
    47         return executorService;
    48     }
    49 
    50     /**
    51      * 取得周期性线程执行器
    52      * @return
    53      */
    54     public ScheduledExecutorService getScheduledExcutorService(){
    55         return (ScheduledExecutorService)executorService;
    56     }
    57 
    58     /**
    59      * 获得手机cup个数
    60      * @return
    61      */
    62     public static int getNumCores() {
    63         int threadCount = Runtime.getRuntime().availableProcessors();
    64         return threadCount;
    65     }
    66 
    67 }

      2、下一步就是在xml文件中插入一个布局

    1 <FrameLayout
    2         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         @Override
    23         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     @Override
    52     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 //        @Override
    59 //        public void run() {
    60 //            handler.sendEmptyMessage(1);
    61 //        }
    62 //    },0,500);//第二个参数是隔多少秒之后开始显示,第三个是隔多久显示下一个
    63 
    64         ThreadPoolManager
    65                 .getInstance()
    66                 .getScheduledExcutorService()
    67                 .scheduleAtFixedRate(new Runnable() {
    68                     @Override
    69                     public void run() {
    70                         handler.sendEmptyMessage(1);
    71                     }
    72                 },0,500, TimeUnit.MILLISECONDS);//第二个参数是隔多少秒之后开始显示,第三个是隔多久显示下一个
    73 }
    74 
    75 
    76     @Override
    77     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             @Override
    13             public void onAnimationEnd(Animation animation) {
    14                 voiceState1.startAnimation(animationIn);
    15             }
    16 
    17             @Override
    18             public void onAnimationRepeat(Animation animation) {
    19 
    20             }
    21         });
    22         animationIn.setAnimationListener(new Animation.AnimationListener() {
    23             @Override
    24             public void onAnimationStart(Animation animation) {
    25 
    26             }
    27 
    28             @Override
    29             public void onAnimationEnd(Animation animation) {
    30                 voiceState1.startAnimation(animationOut);
    31             }
    32 
    33             @Override
    34             public void onAnimationRepeat(Animation animation) {
    35 
    36             }
    37         });

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

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

  • 相关阅读:
    项目开发中需要注意的
    数据库函数
    C#中 ?. 运算符
    字符串格式化String.Format
    day37 进程理论 多进程
    36 网络编程---操作系统 并发
    day35 socket的常用方法,
    day34
    day33天 网络编程udp pycharm控制台输出带颜色
    day32 网络编程初识
  • 原文地址:https://www.cnblogs.com/zhangdiIT/p/5838799.html
Copyright © 2011-2022 走看看