前言:
项目中图文混合使用的太多太多了,但是绝大部分都是静态图片。
然而项目开发中有这么一个需求:显示一个出一个简短的动画(一般都不超过3秒)演示
比如说:一个功能提供很多步骤来教用户做广播体操,那么第一步就显示一个3秒钟的动作图,第二步显示一个几秒钟的动作图。(当然这个需求不是这个功能)
怎么解决呢:一确定这个需求我的第一实现思路便是让美工给我搞几个连续的图片,我使用帧动画来轮回播放 便实现了这个动画。
但是帧动画使用起来太复杂了,一套动作我要搞好久来实现。那么就想Android中支持不支持播放gif格式的图片呢,让美工搞动态图我直接拿来用多方便。
-------------------------------------------------------------------------------------------------------------------
然后我就发现了Fresco,官方网址:http://www.fresco-cn.org/ ,中文文档,很方便查阅
看下官方的描述:
Fresco 是一个强大的图片加载组件。 Fresco 中设计有一个叫做 image pipeline 的模块。它负责从网络,从本地文件系统,本地资源加载图片。为了最大限度节省空间和CPU时间,它含有3级缓存设计(2级内存,1级文件)。 Fresco 中设计有一个叫做 Drawees 模块,方便地显示loading图,当图片不再显示在屏幕上时,及时地释放内存和空间占用。 Fresco 支持 Android2.3(API level 9) 及其以上系统。
------------------------------------------------------------------------------------------------------------------
其他的不管,这篇博客只要看Fresco特性之一:
支持 gif 动态图片 ,也许我们会构造一些自定义的类来实现,但是太复杂了,也太麻烦了,Fresco直接帮你封装好了
------------------------------------------------------------------------------------------------------------------
那么开始看怎么使用Fresco加载显示gif格式的图片了
1、必须要做的事,当然看官方文档也能知道,如何引入Fresco到项目中
Android Studio 或者 Gradle
dependencies { compile 'com.facebook.fresco:fresco:0.6.0+' }
IDEA 和 Eclipse 就是别的方法了,具体看下 http://www.fresco-cn.org/docs/index.html#_
2、配置清单文件添加网络权限,这里具体获取网络gif图片并展示的Demo,加载本地的gif图片 可以不加网络权限
<uses-permission android:name="android.permission.INTERNET"/>
3、布局文件中的使用
(1)xml文件中,加入命名空间,用于给图片设置一些属性
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:fresco="http://schemas.android.com/apk/res-auto">
(2)既然是gif图片,当然也就是图片,而当我们把Fresco导入到项目之后,就有了
com.facebook.drawee.view.SimpleDraweeView 类
1 // 2 // Source code recreated from a .class file by IntelliJ IDEA 3 // (powered by Fernflower decompiler) 4 // 5 6 package com.facebook.drawee.view; 7 8 import android.content.Context; 9 import android.net.Uri; 10 import android.util.AttributeSet; 11 import com.facebook.common.internal.Preconditions; 12 import com.facebook.common.internal.Supplier; 13 import com.facebook.drawee.generic.GenericDraweeHierarchy; 14 import com.facebook.drawee.interfaces.DraweeController; 15 import com.facebook.drawee.interfaces.SimpleDraweeControllerBuilder; 16 import com.facebook.drawee.view.GenericDraweeView; 17 import javax.annotation.Nullable; 18 19 public class SimpleDraweeView extends GenericDraweeView { 20 private static Supplier<? extends SimpleDraweeControllerBuilder> sDraweeControllerBuilderSupplier; 21 private SimpleDraweeControllerBuilder mSimpleDraweeControllerBuilder; 22 23 public static void initialize(Supplier<? extends SimpleDraweeControllerBuilder> draweeControllerBuilderSupplier) { 24 sDraweeControllerBuilderSupplier = draweeControllerBuilderSupplier; 25 } 26 27 public static void shutDown() { 28 sDraweeControllerBuilderSupplier = null; 29 } 30 31 public SimpleDraweeView(Context context, GenericDraweeHierarchy hierarchy) { 32 super(context, hierarchy); 33 this.init(); 34 } 35 36 public SimpleDraweeView(Context context) { 37 super(context); 38 this.init(); 39 } 40 41 public SimpleDraweeView(Context context, AttributeSet attrs) { 42 super(context, attrs); 43 this.init(); 44 } 45 46 public SimpleDraweeView(Context context, AttributeSet attrs, int defStyle) { 47 super(context, attrs, defStyle); 48 this.init(); 49 } 50 51 private void init() { 52 if(!this.isInEditMode()) { 53 Preconditions.checkNotNull(sDraweeControllerBuilderSupplier, "SimpleDraweeView was not initialized!"); 54 this.mSimpleDraweeControllerBuilder = (SimpleDraweeControllerBuilder)sDraweeControllerBuilderSupplier.get(); 55 } 56 } 57 58 protected SimpleDraweeControllerBuilder getControllerBuilder() { 59 return this.mSimpleDraweeControllerBuilder; 60 } 61 62 public void setImageURI(Uri uri) { 63 this.setImageURI(uri, (Object)null); 64 } 65 66 public void setImageURI(Uri uri, @Nullable Object callerContext) { 67 DraweeController controller = this.mSimpleDraweeControllerBuilder.setCallerContext(callerContext).setUri(uri).setOldController(this.getController()).build(); 68 this.setController(controller); 69 } 70 }
那么要显示gif图片的控件的标签便是:
<com.facebook.drawee.view.SimpleDraweeView> </com.facebook.drawee.view.SimpleDraweeView>
注意:SimpleDraweeView 不支持wrap_content
所下载的图像可能和占位图尺寸不一致,如果设置出错图或者重试图的话,这些图的尺寸也可能和所下载的图尺寸不一致。 如果大小不一致,图像下载完之后,假设如果是wrap_content,View将会重新layout,改变大小和位置。这将会导致界面跳跃。 固定宽高比 只有希望显示的固定宽高比时,可以使用wrap_content。 如果希望显示的图片保持一定宽高比例,如果 4:3,则在XML中: <com.facebook.drawee.view.SimpleDraweeView android:id="@+id/my_image_view" android:layout_width="20dp" android:layout_height="wrap_content" <!-- other attributes --> 然后在代码中指定显示比例: mSimpleDraweeView.setAspectRatio(1.33f);
Demo代码:
1 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 2 xmlns:tools="http://schemas.android.com/tools" 3 xmlns:fresco="http://schemas.android.com/apk/res-auto" 4 android:layout_width="match_parent" 5 android:layout_height="match_parent" 6 android:paddingLeft="@dimen/activity_horizontal_margin" 7 android:paddingRight="@dimen/activity_horizontal_margin" 8 android:paddingTop="@dimen/activity_vertical_margin" 9 android:paddingBottom="@dimen/activity_vertical_margin" 10 tools:context=".MainActivity"> 11 12 <com.facebook.drawee.view.SimpleDraweeView 13 android:id="@+id/img" 14 android:layout_width="400dp" 15 android:layout_height="400dp" 16 fresco:placeholderImage="@mipmap/ic_launcher" 17 /> 18 19 </RelativeLayout>
4、然后就是图片所在布局对应的Activity中的使用了
(1)初始化Fresco,注意位置,用过百度地图的应该理解这里,记住位置就行
super.onCreate(savedInstanceState); Fresco.initialize(this); setContentView(R.layout.activity_main);
(2)进行网络gif图片资源的加载并展示
Uri uri = Uri.parse("http://img.huofar.com/data/jiankangrenwu/shizi.gif");
DraweeController draweeController = Fresco.newDraweeControllerBuilder() .setUri(uri) .setAutoPlayAnimations(true) // 设置加载图片完成后是否直接进行播放 .build(); img.setController(draweeController);
效果图:
先给控件一个图片占位,当加载成功的时候显示加载的图片
就这么简单 ,其他的Fresco都会帮我们解决
显示占位图直到加载完成;
下载图片;
缓存图片;
图片不再显示时,从内存中移除