我使用Movie类来显示动画GIF,参考this page。下面是我创建的用于显示gif和调用方法的类。
从SDK 28开始,它已被弃用,建议使用AnimatedImageView。我两者都使用过,结果发现旧的、非官方的方式(使用Movie)更快、更可靠(AnimatedImageView有时会卡顿冻结)。
用于显示带有Movie的动画GIF的类
public class ShowGifView extends View {
private Movie movie;
private int gifImageDrawableId;
private final Context ctx;
private long gifStart = 0;
public ShowGifView(Context context) {
super(context);
setFocusable(true);
ctx = context;
}
@Override
protected void onDraw(Canvas canvas) {
long now = System.currentTimeMillis();
if (gifStart == 0) {
gifStart = now;
}
if (movie != null) {
int duration = movie.duration();
if (duration == 0) {
duration = 1000;
}
int relTime = (int)((now - gifStart) % duration);
movie.setTime(relTime);
int width = this.getWidth();
int height = this.getHeight();
int movieWidth = movie.width();
int movieHeight = movie.height();
canvas.scale((float)width / movieWidth, (float)height / movieHeight);
movie.draw(canvas, 1, 1);
invalidate();
}
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
if(movie != null){
int scale = heightMeasureSpec / movie.height();
setMeasuredDimension(movie.width() * scale, movie.height() * scale);
}else{
setMeasuredDimension(getSuggestedMinimumWidth(), getSuggestedMinimumHeight());
}
}
public int getGifImageDrawableId() {
return gifImageDrawableId;
}
public void setGifImageDrawableId(int gifImageDrawableId) {
this.gifImageDrawableId = gifImageDrawableId;
}
public void drawGif() {
Resources resources = ctx.getResources();
InputStream inputStream = resources.openRawResource(gifImageDrawableId);
movie = Movie.decodeStream(inputStream);
invalidate();
}
}
调用此方法的代码:
private View addAnimatedGif(ConstraintLayout lout, int animatedGif) {
ShowGifView resultView = new ShowGifView(getApplicationContext());
resultView.setLayerType(View.LAYER_TYPE_SOFTWARE, new Paint());
resultView.setGifImageDrawableId(animatedGif);
resultView.drawGif();
ConstraintSet cSet = new ConstraintSet();
lout.addView(resultView);
resultView.setId(View.generateViewId());
int id = resultView.getId();
cSet.clone(lout);
cSet.connect(id, ConstraintSet.START, ConstraintSet.PARENT_ID, ConstraintSet.START, 0);
cSet.connect(id, ConstraintSet.TOP, ConstraintSet.PARENT_ID, ConstraintSet.TOP, 0);
cSet.connect(id, ConstraintSet.END, ConstraintSet.PARENT_ID, ConstraintSet.END, 0);
cSet.connect(id, ConstraintSet.BOTTOM, ConstraintSet.PARENT_ID, ConstraintSet.BOTTOM, 0);
cSet.applyTo(lout);
return resultView;
}