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

简介: 前言: 项目中图文混合使用的太多太多了,但是绝大部分都是静态图片。 然而项目开发中有这么一个需求:显示一个出一个简短的动画(一般都不超过3秒)演示 比如说:一个功能提供很多步骤来教用户做广播体操,那么第一步就显示一个3秒钟的动作图,第二步显示一个几秒钟的动作图。

前言:

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

然而项目开发中有这么一个需求:显示一个出一个简短的动画(一般都不超过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 }
SimpleDraweeView.class

那么要显示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>
activity_main.xml

 

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都会帮我们解决

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

 

相关文章
|
28天前
|
Android开发 UED
Android 中加载 Gif 动画
【10月更文挑战第20天】加载 Gif 动画是 Android 开发中的一项重要技能。通过使用第三方库或自定义实现,可以方便地在应用中展示生动的 Gif 动画。在实际应用中,需要根据具体情况进行合理选择和优化,以确保用户体验和性能的平衡。可以通过不断的实践和探索,进一步掌握在 Android 中加载 Gif 动画的技巧和方法,为开发高质量的 Android 应用提供支持。
|
2月前
|
存储 缓存 编解码
Android经典面试题之图片Bitmap怎么做优化
本文介绍了图片相关的内存优化方法,包括分辨率适配、图片压缩与缓存。文中详细讲解了如何根据不同分辨率放置图片资源,避免图片拉伸变形;并通过示例代码展示了使用`BitmapFactory.Options`进行图片压缩的具体步骤。此外,还介绍了Glide等第三方库如何利用LRU算法实现高效图片缓存。
67 20
Android经典面试题之图片Bitmap怎么做优化
|
3月前
|
数据处理 开发工具 数据安全/隐私保护
Android平台RTMP推送|轻量级RTSP服务|GB28181接入之文字、png图片水印的精进之路
本文探讨了Android平台上推流模块中添加文字与PNG水印的技术演进。自2015年起,为了满足应急指挥及安防领域的需求,逐步发展出三代水印技术:第一代为静态文字与图像水印;第二代实现了动态更新水印内容的能力,例如实时位置与时间信息;至第三代,则优化了数据传输效率,直接使用Bitmap对象传递水印数据至JNI层,减少了内存拷贝次数。这些迭代不仅提升了用户体验和技术效率,也体现了开发者追求极致与不断创新的精神。
|
3月前
|
自然语言处理 定位技术 API
Android经典实战之如何获取图片的经纬度以及如何根据经纬度获取对应的地点名称
本文介绍如何在Android中从图片提取地理位置信息并转换为地址。首先利用`ExifInterface`获取图片内的经纬度,然后通过`Geocoder`将经纬度转为地址。注意操作需在子线程进行且考虑多语言支持。
238 4
|
3月前
|
存储 缓存 Java
Android项目架构设计问题之优化业务接口数据的加载效率如何解决
Android项目架构设计问题之优化业务接口数据的加载效率如何解决
46 0
|
3月前
|
Java Android开发 Kotlin
Android项目架构设计问题之要在Glide库中加载网络图片到ImageView如何解决
Android项目架构设计问题之要在Glide库中加载网络图片到ImageView如何解决
37 0
|
3月前
|
XML 前端开发 Android开发
Android经典实战之Kotlin中实现圆角图片和圆形图片
本文介绍两种实现圆角图像视图的方法。第一种是通过自定义Kotlin `AppCompatImageView`,重写`onDraw`方法使用`Canvas`和`Path`进行圆角剪裁。第二种利用Android Material库中的`ShapeableImageView`,简单配置即可实现圆角效果。两种方法均易于实现且提供动态调整圆角半径的功能。
73 0
|
Android开发 数据格式 XML
Android异步加载图片详解之方式二(3)
main.xml如下:   listviewitem.xml如下:   ...
815 0
|
缓存 Java Android开发
Android异步加载图片详解之方式二(2)
FileCache.java如下: package com.cn.loadImages; import java.io.File; import java.
897 0
|
Android开发
Android异步加载图片详解之方式二(1)
MainActivity.java如下: package com.cn.perfectlistview; import java.util.ArrayList; import android.
898 0