通常情况下,ImageView是不支持Gif动画的,所以我们要向支持Gif的话,必须自己来处理。
在这里我们就不是对Drawable的包装了,我们是对Drawable的重新实现。同时由于Gif具有动画,所以又同时实现了Runnable,Animatable接口。
源码:
public class GifDrawable extends Drawable implements Runnable, Animatable {
private int byteCount;//数据大小
private int rate = 300;//播放的频率,多长时间刷新一次
private volatile boolean running;//是否正在运行
private final Movie movie;//gif的具体内容
private final int duration;//gif播放的时长
private final long begin = SystemClock.uptimeMillis();
public GifDrawable(Movie movie, int byteCount) {
this.movie = movie;
this.byteCount = byteCount;
this.duration = movie.duration();
}
public int getDuration() {
return duration;
}
public Movie getMovie() {
return movie;
}
public int getByteCount() {
if (byteCount == 0) {
byteCount = (movie.width() * movie.height() * 3) * (5/*fake frame count*/);
}
return byteCount;
}
public int getRate() {
return rate;
}
public void setRate(int rate) {
this.rate = rate;
}
@Override
public void draw(Canvas canvas) {
try {
int time = duration > 0 ? (int) (SystemClock.uptimeMillis() - begin) % duration : 0;
movie.setTime(time);
movie.draw(canvas, 0, 0);//git帧绘制
start();
} catch (Throwable ex) {
LogUtil.e(ex.getMessage(), ex);
}
}
@Override
public void start() {
if (!isRunning()) {
running = true;
run();
}
}
@Override
public void stop() {
if (isRunning()) {
this.unscheduleSelf(this);
}
}
@Override
public boolean isRunning() {
return running && duration > 0;
}
@Override
public void run() {
if (duration > 0) {
this.invalidateSelf();//页面失效
this.scheduleSelf(this, SystemClock.uptimeMillis() + rate);//过会儿再重绘
}
}
@Override
public void setAlpha(int alpha) {
}
@Override
public int getIntrinsicWidth() {
return movie.width();
}
@Override
public int getIntrinsicHeight() {
return movie.height();
}
@Override
public void setColorFilter(ColorFilter cf) {
}
@Override
public int getOpacity() {
return movie.isOpaque() ? PixelFormat.OPAQUE : PixelFormat.TRANSLUCENT;
}
}