1、使用的是Fresco的三方庫
官網文檔:https://www.fresco-cn.org/docs/progress-bars.html
2、支持播放GIF
這裏只是介紹支持播放GIF的功能,因此步驟也都是GIF的步驟
1.引入Fresco
爲了支持獲取GIF播放一遍的時長,就要引入0.13.0之後的版本,可是0.14.0改變了android studio的分包機制,可能會致使編譯問題,因此仍是選擇0.13.0版本。html
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 viewandroid
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)ide
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播放一遍就中止,而後顯示一個本身想要的界面。
從官方文檔看到以下信息:oop
手動控制動畫圖播放post
也許你但願在代碼中直接控制動畫的播放。這種狀況下,你須要監聽圖片是否加載完畢,而後才能控制動畫的播放:動畫
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 的訪問。ui
若是有可用動畫的話,可對動畫進行靈活的控制:spa
Animatable animatable = mSimpleDraweeView.getController().getAnimatable(); if (animatable != null) { animatable.start(); // later animatable.stop(); }
因此個人思路以下:
獲取GIF播放一遍的時長,播放一遍後,讓GIF的animatable中止,並顯示想要顯示的view。如下是個人代碼.net
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); } } }