Android中动态显示gif图片

来源:互联网 发布:java中什么是线程安全 编辑:程序博客网 时间:2024/06/10 08:38

android所带的控件里面没有能够显示gif图片的

网上的解决方法大致有三种

第一:先将gif图片分拆为N帧(由美工/软件完成),然后逐次播放;

第二:利用java代码将图片分拆为N帧;

第三:android里面有一个Movie类,可以使用它来播放gif动画(此类位于android.graphics包下)

前面两种的思路是一样的,第二种网上有jar包可以下载用(在资源中已经上传)。

第一种对于帧数较多的图片太过于繁琐,不提倡使用。

先来解释一下第二种的方法:

GifAction.java 观察者类,监视GIF是否加载成功
GifFrame.java 里面三个成员:当前图片、延时、下张Frame的链接。
GifDecoder.java 解码线程类
GifView.java 主类,包括常用方法,如GifView构造方法、设置图片源、延迟、绘制等。

 

public interface GifAction {/** * gif解码观察者 * @param parseStatus 解码是否成功,成功会为true * @param frameIndex 当前解码的第几帧,当全部解码成功后,这里为-1 */public void parseOk(boolean parseStatus,int frameIndex);}


 

//线程操作gif图片解码public class GifDecoder extends Thread


 

//gif框架public class GifFrame{/** * 构造函数 *  * @param im *            图片 * @param del *            延时 */public GifFrame(Bitmap im, int del){image = im;delay = del;}/** 图片 */public Bitmap image;/** 延时 */public int delay;/** 下一帧 */public GifFrame nextFrame = null;}


 

/** * GifView<br> * 本类可以显示一个gif动画,其使用方法和android的其它view(如imageview)一样。<br> * 如果要显示的gif太大,会出现OOM的问题。 *  * @author liao *  */public class GifView extends View implements GifAction


 

应用如下:

1-把GifView.jar加入你的项目。
2-在xml中配置GifView的基本属性,GifView继承自View类,和Button、ImageView一样是一个UI控件。如:
<com.ant.liao.GifView android:id="@+id/gif2"
 android:layout_height="wrap_content" android:layout_width="wrap_content"
 android:paddingTop="4px" android:paddingLeft="14px" android:enabled="false" />
3-在代码中配置常用属性:
// 从xml中得到GifView的句柄
gf1 = (GifView) findViewById(R.id.gif1);
// 设置Gif图片源
gf1.setGifImage(R.drawable.gif1);
// 添加监听器
gf1.setOnClickListener(this);
// 设置显示的大小,拉伸或者压缩
gf1.setShowDimension(300, 300);
// 设置加载方式:先加载后显示、边加载边显示、只显示第一帧再显示
gf1.setGifImageType(GifImageType.COVER);

 

然后分析下第三种方法:

,为了显示gif图片,我们需要用到Movie类和自定义控件(包括自定义属性)

首先,我们来自定义控件属性:

在res/values里面建立xml文件,习惯性命名为attrs.xml(可以命名为其他名字)

在attrs.xml里面增加属性如下:

<declare-styleable name="GifView">        <attr name="src" format="integer" />    </declare-styleable>

 

这里我只增加了一个属性,就是设置src文件。

属性设置好了,那怎么将这个src属性与java代码对应起来呢,这个就需要到构造函数里面处理了

public GifView(Context context, AttributeSet attrs){  super(context, attrs);  TypedArray ta = context.obtainStyledAttributes(attrs,                  R.styleable.GifView);  //这里用到了attrs.xml里面定义的GifView  int taCount = ta.length();   //获得属性的个数    for (int i=0;i<taCount;i++){  //处理所有属性,由于我只定义了一个src属性,所以就只处理src属性   if (R.styleable.GifView_src == ta.getIndex(i)) {    int id = ta.getResourceId(R.styleable.GifView_src, 0); //这里的参数是前面的GifView + _ + src链接起来    if (0 != id) {     setSrc(id);  //对应的函数,即在xml里面设置了src,相应的处理就会在setSrc函数里面进行    }   }  }  ta.recycle(); } 


下面是setSrc函数:

public void setSrc(int id){  gifMovie = Movie.decodeStream(getResources().openRawResource(id)); //gifMovie为Movie类型 }


接下来是view的onDraw函数,这也是绘画动画的关键

public void onDraw(Canvas canvas){   long now = android.os.SystemClock.uptimeMillis(); //获得当前时间         if (lStartTime == 0) {   // first time          lStartTime = now;         }         if (gifMovie != null) {             int dur = gifMovie.duration();  //获得gif文件的动画周期             if (dur == 0) {                 dur = 1000;             }             int relTime = (int)((now - lStartTime) % dur);             gifMovie.setTime(relTime);  //设置播放时间点             gifMovie.draw(canvas, getWidth() - gifMovie.width(),  //播放(即绘画)                         getHeight() - gifMovie.height());             invalidate();         }}


 

下面在main.xml文件里面加入自定义的GifView控件

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:gif="http://schemas.android.com/apk/res/com.gif.demo"    android:orientation="vertical"    android:layout_width="fill_parent"    android:layout_height="fill_parent"    ><TextView     android:layout_width="fill_parent"    android:layout_height="wrap_content"    android:text="@string/hello"    /><com.gif.demo.GifView android:layout_width="wrap_content" android:layout_height="wrap_content" gif:src="@drawable/lion"/></LinearLayout>


其中xmlns:gif="http://schemas.android.com/apk/res/com.gif.demo"
即gif为自己定义的namespace,com.gif.demo对应于自己的包名,即activity对应的包名

最后在activity里面setContentView(R.layout.main)就ok了

原创粉丝点击