Android开发案例 - 图库
本文不涉及UI方面的内容, 如果您是希望了解UI方面的访客, 请跳过此文.
本文将要详细介绍如何实现流畅加载本地图库. 像平时用得比较多应用, 如微信(见下图), 微博等应用, 都实现了图库功能, 其中主要功能包括:
- 默认显示所有图片
- 按目录显示图片
另外, 界面要素包括:
- 图片缩略图
- 图片目录列表以及目录中包含的图片数

讨论: 在Android上, 如何实现流畅加载本地照片的相册?
知识要点
- ContentProvider - 数据存取接口
- CursorLoader - Cursor异步加载器
- Android Universal Image Loader
p.s. 实现图库的难点就在于, 如何快速的查询出图片以及目录信息, 貌似 Android 没有直接提供这样的接口, 我们只可以用 android.provider.MediaStore.Images.Media 和 android.provider.MediaStore.Images.Thumbnails. 我们虽然能使用 Thumbnails 查询出缩略图信息和图片ID, 但是它没有提供图片的详细信息, 另外, 如果用于保存缩略图的信息或者目录被(意外或者人为)删除了, 那使用 Thumbnails 基本上就没有什么意义了. 因此, 我们在这里使用 Media 来查询图片以及目录.
实现代码
> 定义
static final Uri CONTENT_URI = Media.EXTERNAL_CONTENT_URI;
static final String SORT_ORDER = Media.DATE_MODIFIED + " DESC";
在这里, 我们只查询sdcard上的图片, 并按照修改时间倒序排列.
> 查询图片
代码略, 直接使用 CursorLoader 按 SORT_ORDER 顺序加载图片, 如果指定了目录, 则设置 Media.BUCKET_ID + "=?" 的查询条件
> 查询目录
和查询图片一样, 也使用CursorLoader来加载数据, 只不过设置的参数不同而已, 如下:
// 方法一
static final String[] PROJECTION_D = {
"DISTINCT " + Media.BUCKET_ID,
Media.BUCKET_DISPLAY_NAME,
"COUNT(*) AS " + Media._COUNT};
// 方法二
static final String[] PROJECTION = {
Media.BUCKET_ID,
Media.BUCKET_DISPLAY_NAME,
Media._ID,
"COUNT(*) AS " + Media._COUNT};
static final String SELECTION = "1=1) GROUP BY (" + Media.BUCKET_ID;
static final String[] SELECTION_ARGS = null;
需要说明的是, 如果对应的目录不需要显示首张图片的缩略图, 那么可以使用方法一, 否则使用方法二(PROJECTION 要与 SELETION 配合使用, 而方法一不需要). 其他参数对应设置到CursorLoader即可.
优化策略
最后, 需要提到的一点就是, 我们使用 UIL(即, Android Universal Image Loader) 加载图片, 但是每次加载都是我们查询出来的原图, 按照github上演示代码的全局初始设定, 加载到三五屏, 第一屏的图片就已经不在内存缓存里, 如果重新滚动到第一屏要显示第一屏图片的话, 就还得从原图读取, 用户体验就很差了. 而我们看到Android相册, 微信相册等应用, 加载很流畅. 通过观察这些应用缓存, 能看到只要浏览很多未被浏览的图片, 那缓存就会变大. 因此, 可以想到的可实现的方式就是:
- 利用UIL缓存原图为较小尺寸的缩略图, 比如320px或者96px
到这里, 按此方法实现的图库的性能以及用户体验基本和Android相册差不多了. 此方法唯一不足的是, 需要应用自己缓存缩略图, 可以假想下, 如果手机上已安装的80%的应用都有这样的一个功能页面, 那岂不是每个应用都要自己生成一套缩略图?
END.
Android开发案例 - 图库的更多相关文章
- AllJoyn+Android开发案例-android跨设备调用方法
AllJoyn+Android开发案例-android跨设备调用方法 项目须要涉及AllJoyn开源物联网框架.前面主要了解了一些AllJoyn主要的概念.像总线,总线附件,总线对象,总线接口这种概念 ...
- Android开发案例 设置背景图片轮播
点击按钮实现图片轮播效果 实践案例: xml <?xml version="1.0" encoding="utf-8"?> <LinearLa ...
- Android开发案例 – 在AbsListView中使用倒计时
在App中, 有多种多样的倒计时需求, 比如: 在单View上, 使用倒计时, 如(如图-1) 在ListView(或者GridView)的ItemView上, 使用倒计时(如图-2) 图-1 图-2 ...
- Android开发案例 - 淘宝商品详情
所有电商APP的商品详情页面几乎都是和淘宝的一模一样(见下图): 采用上下分页的模式 商品基本参数 & 选购参数在上页展示 商品图文详情等其他信息放在下页展示 知识要点 垂直方向的ViewPa ...
- Android开发案例 - 自定义虚拟键盘
所有包含IM功能的App(如微信, 微博, QQ, 支付宝等)都提供了Emoji表情之类的虚拟键盘, 如下图: 本文只着重介绍如何实现输入法键盘和自定义虚拟键盘的流畅切换, 而不介绍如何实现虚 ...
- [Deprecated!] Android开发案例 - 微博正文
Deprecated! 更好的实现方式: 使用 android.support.design.widget.CoordinatorLayout. 本文详细介绍如何实现如下图中的微博正文页面效果, 其中 ...
- Android开发案例 - 欢迎界面
本文详细描述了如何实现如下图中的微信启动界面. 该类启动界面的特点是在整个Application的生命周期里, 它只会出现在第一次进入应用时, 即便按回退键到桌面之后. 使用该类启动界面的应用还有: ...
- Android开发案例 - 淘宝商品详情【转】
http://erehmi.cnblogs.com/ 所有电商APP的商品详情页面几乎都是和淘宝的一模一样(见下图): 采用上下分页的模式 商品基本参数 & 选购参数在上页展示 商品图文详情等 ...
- Android开发案例 点击按钮出现 简易的消息提示框
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android=&quo ...
随机推荐
- 如何使用RobotFramework编写好的测试用例
如何使用Robot Framework编写优秀的测试用例 概述 命名 测试套件命名 测试用例命名 关键字命名 setup和teardown的命名 文档 测试套件文档 测试用例文档 用户关键字文档 测试 ...
- Redola.Rpc 的一个小目标
Redola.Rpc 的一个小目标 Redola.Rpc 的一个小目标:20000 tps. Concurrency level: 8 threads Complete requests: 20000 ...
- Web API 入门指南 - 闲话安全
Web API入门指南有些朋友回复问了些安全方面的问题,安全方面可以写的东西实在太多了,这里尽量围绕着Web API的安全性来展开,介绍一些安全的基本概念,常见安全隐患.相关的防御技巧以及Web AP ...
- git 常见命令解析
转载自http://www.rainkong.net/post/git-image.html 之前用的都是svn ,git还是要了解的,万一哪天要用了呢
- Spark 开发中遇到的一些问题
1.StackOverflowError 问题:简单代码记录 : for (day <- days){ rdd = rdd.union(sc.textFile(/path/to/day) ... ...
- linux下如何添加一个用户并且让用户获得root权限
1.添加用户,首先用adduser命令添加一个普通用户,命令如下: #adduser tommy //添加一个名为tommy的用户 #passwd tommy //修改密码 Changing pass ...
- eclipse 突然 一直在loading descriptor for XXX (XXX为工程名)Cancel Requested
问题: eclipse 启动后,啥也不干,就一直在loading descriptor for XXX (XXX为工程名),,其他什么操作都不能操作. 如下图所示,保存文件也无法保存. 这个怎么办? ...
- JavaScript高级编程 (1) - javscript是什么
<重温javascript>这是一系列 javascript 的学习笔记,部分内容摘自书本或者网络,我这里只是基于自己的理解进行了梳理整理. 一个完整的 javscript 实现是由以下3 ...
- 移动端事件对象touches的误区
不想长篇大论,也是自己遗留下的一个错误的理解 在移动端触屏事件有四个 // 手势事件 touchstart //当手指接触屏幕时触发 touchmove //当已经接触屏幕的手指开始移动后触发 tou ...
- z-index--记录七
1.z-index用来控制元素重叠时堆叠顺序. 适用于:已经定位的元素(即position:relative/absolute/fixed). 2.不使用z-index的时候,堆叠顺序如下(从下到上) ...