目前支持Gif播放的开源库还是有的,不过经分析:
GifView:如果Gif图片太大会导致OOM;
SimpleDraweeView:是由Facebook提供的,它的弊端是:不支持 wrap_content 属性。
你还在为开发中频繁切换环境打包而烦恼吗?快来试试 Environment Switcher 吧!使用它可以在app运行时一键切换环境,而且还支持其他贴心小功能,有了它妈妈再也不用担心频繁环境切换了。https://github.com/CodeXiaoMai/EnvironmentSwitcher
dependencies {
compile 'pl.droidsonroids.gif:android-gif-drawable:1.2.2'
}
buildscript {
repositories {
mavenCentral()
}
}
allprojects {
repositories {
mavenCentral()
}
}
最简单的方法是使用GifImageView(或GifImageButton)和使用ImageView的方法是一样的:
<pl.droidsonroids.gif.GifImageView
android:id="@+id/activity_gif_giv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:src="@drawable/anim"/>
GifImageView会自动识别”android:src”或者”android:background”的内容是否Gif文件,如果是Gif就播放Gif文
件,否则就像我们熟悉的ImageView或者ImageButton一样展示。这样其实Gif就已经可以播放了,就这么简单。
当然,你也可以在Java代码中通过调用setImageResource(int resId) 或者setBackgroundResource(int resId)
为GifImageView, GifImageButton 和GifTextView 设置Gif的资源。除了这两种方法以外,还支持多种来源,例如:
// 从Assets中获取
GifDrawable gifFromAssets = new GifDrawable(getAssets(), "anim.gif");
// 从drawable或者raw中获取
GifDrawable gifFromResource = new GifDrawable(getResources(), R.drawable.anim);
// 从文件中获取
File gifFile = new File(getFilesDir(), "anim.gif");
GifDrawable gifFromFile = new GifDrawable(gifFile);
//从输入流中获取,如果GifDrawable不再使用,输入流会自动关闭。另外,你还可以通过调用recycle()关闭不再使用的输入流
InputStream inputStream = new FileInputStream(gifFile);
BufferedInputStream bis = new BufferedInputStream(inputStream, 1024 * 1024);
GifDrawable gifFromStream = new GifDrawable(bis);
可以发现,我们获取到的都是一个GifDrawable对象,这个GifDrawable是干什么的呢?我们首先说Drawable,
大家不陌生吧,IamgeView.setImageDrawable(Drawable drawable);相信这个方法也都使用过,那么好了
GifDrawable和我们平时使用的Drawable的用途是一样的,调用gifImageView.setImageDrawable()就可以
了。当然,GifDrawable还支持其他的方式,这里就不在赘述,有兴趣的可以到GitHub查看。
注意:GifDrawable所引用的资源需要能自动跳转到第一帧,也就是支持循环播放
GifDrawable实现了Animatable和MediaPlayerControl的接口,所以我们可以使用它们的方法,如:
我们可以像使用VideoView一样,通过MediaPlayer控制Gif的播放并展示它的播放进度
private GifImageView mGifImageView;
@Override
protected void onCreate (Bundle savedInstanceState) {
mGifImageView = (GifImageView) findViewById(R.id.activity_gif_giv);
try {
GifDrawable gifDrawable = new GifDrawable(getAssets(), "anim.gif");
mGifImageView.setImageDrawable(gifDrawable);
final MediaController mediaController = new MediaController(this);
mediaController.setMediaPlayer((GifDrawable) mGifImageView.getDrawable());
/**
* 也许你会像我一样,当看到上面一行代码时会纳闷,为什么setMediaPalyer传入的参数会是一个
* GifDrawable对象呢,它需要的参数类型是MediaPlayerControl。。。
* 还永德我们前面提到GifDrawable实现了MediaPlayerControl接口吗?
* 嗯。。。哦,,,恍然大明白了
*/
mediaController.setAnchorView(mGifImageView);
mGifImageView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mediaController.show();
}
});
} catch (IOException e) {
e.printStackTrace();
}
}
GifDrawable提供以下方法,用于获取Gif的元数据
一个GifDrawable实例被多个GifImageView关联,那么通常只胡最后一个GifImageView会播放动画,而前面
的GifImageView只会显示第一帧。为了解决这个问题multicallback出场了:
MultiCallback multiCallback = new MultiCallback();
try {
final GifDrawable gifDrawable = new GifDrawable(getAssets(), "anim.gif");
mGifImageView.setImageDrawable(gifDrawable);
multiCallback.addView(mGifImageView);
mGifImageView2.setImageDrawable(gifDrawable);
multiCallback.addView(mGifImageView2);
gifDrawable.setCallback(multiCallback);
} catch (IOException e) {
e.printStackTrace();
}
这样两个动画都动起来了。MultiCallBack还可以同时控制两个GifImageView,比如,动画播放5秒后,全部停止。
multiCallback.scheduleDrawable(gifDrawable, new Runnable() {
@Override
public void run() {
gifDrawable.stop();
}
}, 5 * 1000);