Glide入门教程(4)播放Gif动画与本地视频

播放动画

       如果你的app需要支持Gif,Glide的简单会让体验更惊艳。想要播放Gif,只要使用之前处理图片的类似的方法:

1
2
3
4
5
6
String gifUrl = "http://i.kinja-img.com/gawker-media/image/upload/s--B7tUiM5l--/gf2r69yorbdesguga10i.gif";

Glide
.with( context )
.load( gifUrl )
.into( imageViewGif );

       上面的代码会在ImageView里显示Gif,并自动播放。Glide另外一个非常棒的功能是你仍然可以使用标准的调用去处理Gif。

1
2
3
4
5
6
Glide  
.with( context )
.load( gifUrl )
.placeholder( R.drawable.cupcake )
.error( R.drawable.full_cake )
.into( imageViewGif );

Gif 检查

       Glide接受Gif和图片作为load()的参数。上面代码中潜在的一个问题,如果提供的源不是Gif,可能是一个普通的图片。作为开发者,你当然希望那个URL是一个Gif,但Glide不能自动检测到底是不是,这样引入了一个额外的方法asGif()强迫生成一个Gif:

1
2
3
4
5
6
Glide
.with( context )
.load( gifUrl )
.asGif()
.error( R.drawable.full_cake )
.into( imageViewGif );

       如果gifUrl是一个gif,没有异常发生。但如果gifUrl不是一个Gif,即使是一个完好的图片(非Gif),Glide也会加载失败。.error()回调方法会被调用,并加载错误占位图。总之,如果添加.asGif(),这样的话就只能加载gif文件,如果不加,既可以加载图片也可以加载.gif。

解决加载Gif文件非常慢的情况

       为其添加缓存策略:

1
Glide.with(MainActivity.this).load(url).asGif().diskCacheStrategy(DiskCacheStrategy.SOURCE).into(imageView);

       其中缓存策略可以为Source及None,None为不缓存,Source缓存原型;不可以使用ALL和Result。

把Gif当作Bitmap播放

       如果你的app需要显示一组网络URL,可能包括普通的图片或者Gif。在一些情况下,你可能并不在意是否要播放完整的Gif。如果你只是想要显示Gif的第一帧,当URl指向的的确是Gif,你可以调用asBitmap()将其作为常规图片显示。

1
2
3
4
5
Glide  
.with( context )
.load( gifUrl )
.asBitmap()
.into( imageViewGifAsBitmap );

注意事项

       实际中加载gif并没有上述的那么简单,可能会遇到很多问题,比如加载慢,比如OOM。

  • git图片大小,图片格式是否正确,你可以查看下你需要加载的gif图片大小,需要多长时间。太大的图片,加载慢,又浪费流量,不利于用户体验。
  • 网速是否正常,可以从chrome里加载一下该图,看需要多长时间。
  • 在ListView等列表控件中滑动的时候,考虑添加 Glide.with(context).pause|resumeRequests() ,可以参考github上的开发者答复,即如下代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
class PauseOnFling extends OnScrollListener {
private static final int FLING_JUMP_LOW_THRESHOLD = 80;
private static final int FLING_JUMP_HIGH_THRESHOLD = 120;

private final RequestManager glide;
private boolean dragging = false;

public PauseOnFling(RequestManager glide) {
this.glide = glide;
}

@Override public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
dragging = newState == SCROLL_STATE_DRAGGING;
if (glide.isPaused()) {
if (newState == SCROLL_STATE_DRAGGING || newState == SCROLL_STATE_IDLE) {
// user is touchy or the scroll finished, show images
glide.resumeRequests();
} // settling means the user let the screen go, but it can still be flinging
}
}

@Override public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
if (!dragging) {
// TODO can be made better by a rolling average of last N calls to smooth out patterns like a,b,a
int currentSpeed = Math.abs(dy);
boolean paused = glide.isPaused();
if (paused && currentSpeed < FLING_JUMP_LOW_THRESHOLD) {
glide.resumeRequests();
} else if (!paused && FLING_JUMP_HIGH_THRESHOLD < currentSpeed) {
glide.pauseRequests();
}
}
}
}
  • 开启Glide的相关log,查看异常原因,具体问题具体分析。
  • 访问 https://github.com/bumptech/glide 看一下里面的issue,搜索一下相关的关键字。

控制动画的播放次数

       有的时候我们需要控制动画的播放次数,而默认的加载则是循环播放的,Glide也没有开放单独的api接口用来控制gif,这时可以通过GlideDrawableImageViewTarget(ImageView view, int maxLoopCount)来实现, 其中第二个参数表示播放的次数:

1
Glide.with(this).load(...).into(new GlideDrawableImageViewTarget(iv, 1));

播放本地视频

       Glide也能播放存储在手机上的本地视频。假设你能通过用户选择获取到视频文件的路径:

1
2
3
4
5
6
String filePath = "/storage/emulated/0/Pictures/example_video.mp4";

Glide
.with( context )
.load( Uri.fromFile( new File( filePath ) ) )
.into( imageViewGifAsBitmap );

       这里只对本地视频有效,对于并非存在本地的视频(如网络URL)并不支持。

参考资料:
签到钱就到 Glide入门教程——6.播放Gif & 视频
LichFaker Glide 加载gif的一些个人总结
荒年-yang Android Glide加载Gif非常慢的解决

Fork me on GitHub