Android项目实战(三十):Fresco加载gif图片并播放

前言:

项目中图文混合使用的太多太多了,但是绝大部分都是静态图片。

然而项目开发中有这么一个需求:显示一个出一个简短的动画(一般都不超过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都会帮我们解决

显示占位图直到加载完成;
下载图片;
缓存图片;
图片不再显示时,从内存中移除

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏前端人人

React第三方组件1(路由管理之Router的使用⑤按需加载-下)

本教程总共6篇,每日更新一篇,请关注我们!你可以进入历史消息查看以往文章,也敬请期待我们的新文章! 1、React第三方组件1(路由管理之Router的使用①...

30060
来自专栏前端人人

React第三方组件2(状态管理之Refast的使用②异步修改state)

本教程总共5篇,每日更新一篇,请关注我们!你可以进入历史消息查看以往文章,也敬请期待我们的新文章! 1、React第三方组件2(状态管理之Refast的使用①...

28130
来自专栏h5

支付宝小程序弹窗插件开发|仿微信/android/ios弹窗效果

支付宝小程序弹窗交互组件和微信小程序弹窗功能都差不多,对功能有比较多的限制,尤其想要实现丰富一些的弹窗场景就只能自己写组件实现了。

68620
来自专栏jeremy的技术点滴

前端ReactJS技术介绍

44930
来自专栏向治洪

react native实现上拉加载下拉刷新

前言 我们在做原生app开发的时候,很多场景都会用到下拉刷新、上拉加载的操作,Android中如PullToRefreshListView,ios中如MJRef...

31480
来自专栏Golang语言社区

Go语言服务器开发之简易TCP客户端与服务端实现方法

Go语言具备强大的服务器开发支持,这里示范了最基础的服务器开发:通过TCP协议实现客户端与服务器的通讯。 一 服务端,为每个客户端新开一个goroutine 代...

385140
来自专栏Core Net

微信小程序:动画(Animation)

官方文档是这样说的:①创建一个动画实例 animation。②调用实例的方法来描述动画。③最后通过动画实例的 export 方法导出动画数据传递给组件的 ani...

3K10
来自专栏Android干货

Android项目实战(十一):moveTaskToBack(boolean ) 方法的使用

30350
来自专栏滕先生的博客

react-native 跨平台滤镜集成

44980
来自专栏前端下午茶

Vue项目预渲染机制引入实践

周末想顺便把已经做好静态页面的webApp项目做一下SEO优化,由于不想写蹩脚的SSR代码,所以准备采用预渲染,本来想着网上有这么多预渲染的文章,随便找个来跟着...

74220

扫码关注云+社区

领取腾讯云代金券