fresco gif 时间
一、使用的是Fresco的三方库
官网文档:https://www.fresco-cn.org/docs/progress-bars.html
二、支持播放GIF
这里只是介绍支持播放GIF的功能,所以步骤也都是GIF的步骤
1.引入Fresco
为了支持获取GIF播放一遍的时长,就要引入0.13.0以后的版本,但是0.14.0改变了android studio的分包机制,可能会导致编译问题,所以还是选择0.13.0版本。
dependencies {
compile fileTree(include: ['*.jar'], dir: 'libs')
compile 'com.facebook.fresco:fresco:0.13.0'
compile 'com.facebook.fresco:animated-gif:0.13.0'
}
我这里实现了在整个屏幕上添加一个GIF view
2.获取root view
private static ViewGroup getRootGroup(Activity activity) {
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.KITKAT) {
return (ViewGroup) activity.findViewById(android.R.id.content);
} else {
return (ViewGroup) activity.getWindow().getDecorView().getRootView();
}
}
上面获取rootview
3.new一个SimpleDraweeView(com.facebook.drawee.view.SimpleDraweeView)
SimpleDraweeView gifView = (SimpleDraweeView) activity.findViewById(R.id.gif_tip_view);
if (gifView == null) {
gifView = new SimpleDraweeView(activity);
gifView.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View view, MotionEvent motionEvent) {
//触摸之后的事件不往后传递
return true;
}
});
gifView.setPadding(0, HtscSystemUtil.getStatusBarHeight(activity), 0, 0);
// GIF图片填充XY轴
gifView.getHierarchy().setActualImageScaleType(ScalingUtils.ScaleType.FIT_XY);
gifView.setId(R.id.gif_tip_view);
}
4.下面就是关键代码了
很多GIF本身都是可以循环播放的,但是我这里想实现GIF播放一遍就停止,然后显示一个自己想要的界面。
从官方文档看到如下信息:
手动控制动画图播放
也许你希望在代码中直接控制动画的播放。这种情况下,你需要监听图片是否加载完毕,然后才能控制动画的播放:
ControllerListener controllerListener = new BaseControllerListener<ImageInfo>() {
@Override
public void onFinalImageSet(
String id,
@Nullable ImageInfo imageInfo,
@Nullable Animatable anim) {
if (anim != null) {
// 其他控制逻辑
anim.start();
}
}
};
Uri uri;
DraweeController controller = Fresco.newDraweeControllerBuilder()
.setUri(uri)
.setControllerListener(controllerListener)
// 其他设置(如果有的话)
.build();
mSimpleDraweeView.setController(controller);
另外,controller提供对Animatable 的访问。
如果有可用动画的话,可对动画进行灵活的控制:
Animatable animatable = mSimpleDraweeView.getController().getAnimatable();
if (animatable != null) {
animatable.start();
// later
animatable.stop();
}
所以我的思路如下:
获取GIF播放一遍的时长,播放一遍后,让GIF的animatable停止,并显示想要显示的view。以下是我的代码
ControllerListener controllerListener = new BaseControllerListener<ImageInfo>() {
@Override
public void onFinalImageSet(String id, ImageInfo imageInfo, final Animatable animatable) {
if (animatable != null) {
int duration = 0;
try {
Field field = AbstractAnimatedDrawable.class.getDeclaredField("mTotalLoops");
field.setAccessible(true);
field.set(animatable, 1);
} catch (Exception e) {
e.printStackTrace();
}
animatable.start();
if (animatable instanceof AbstractAnimatedDrawable) {
// 只有fresco 0.13.0+才有getDuration()的方法
duration = ((AbstractAnimatedDrawable) animatable).getDuration();
}
if (duration > 0) {
finalImageView.postDelayed(new Runnable() {
@Override
public void run() {
if (animatable.isRunning()) {
animatable.stop();
rootGroup.removeView(finalImageView);
ViewGroup parent;
View gifEndView = getGifEndView(type, rootGroup, finalImageView, activity);
if ((parent = (ViewGroup) gifEndView.getParent()) != null) {
parent.removeView(gifEndView);
}
rootGroup.addView(gifEndView);
}
}
}, duration);