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了