布局及特效  gallery3d 的精华
一、布局
gallery3d的界面生成和普通的应用程序不一样。普通程序一般一个界面就是一个activity,布局用xml或代码都可以实现,界面切换是activity的切换方式;而gallery3d没有用android的UI系统,而是用opengl画出来的,即界面是在同一个 activity的,如主界面,缩略图界面,单张图片查看界面,标记界面等都属于同一个activity。那么这界面布局不同的界面是如何组合到一起的呢?分析代码,可以把它看成一个状态机:  
1、标记模式   public static final int MODE_SELECT = 1;(HudLayer)
包含了主界面标记模式,缩略界面矩阵游览时标记模式、缩略图界面分类游览时标记模式3个界面
2、普通模式  public static final int MODE_NORMAL = 0;(HudLayer)
包含了

Java代码  
  1. public static final int STATE_MEDIA_SETS = 0;主界面
  2. public static final int STATE_GRID_VIEW = 1;缩略图矩阵浏览
  3. public static final int STATE_FULL_SCREEN = 2;查看界面
  4. public static final int STATE_TIMELINE = 3;缩略图界面分类浏览

有了以上状态分类后,在渲染的时候就能根据些界面的组成来定哪些控件譔隐藏,哪些要显示了。
下面是基本控件:

Java代码  
  1. com.cooliris.media.GridLayer
  2. com.cooliris.media.BackgroundLayer
  3. com.cooliris.media.HudLayer
  4. com.cooliris.media.ImageButton
  5. com.cooliris.media.TimeBar
  6. com.cooliris.media.MenuBar
  7. com.cooliris.media.PopupMenu
  8. com.cooliris.media.PathBarLayer

在渲染时,每一帧所有界面上的元素都画了,由于根据上面的状态只把特定窗口的特定元素显示出来,其它窗口中的隐藏,所以不会乱。
Layer是上面控件的基类,上面控件的类也就有了下面两个方法来隐藏不譔显示的界面元素。

Java代码  
  1. public boolean isHidden() {
  2. return mHidden;
  3. }
  4. public void setHidden(boolean hidden) {
  5. if (mHidden != hidden) {
  6. mHidden = hidden;
  7. onHiddenChanged();
  8. }
  9. }

下面是根据上面分类来画不同元素所用的标识:

Java代码  
  1. public static final int PASS_THUMBNAIL_CONTENT = 0;
  2. public static final int PASS_FOCUS_CONTENT = 1;
  3. public static final int PASS_FRAME = 2;
  4. public static final int PASS_PLACEHOLDER = 3;
  5. public static final int PASS_FRAME_PLACEHOLDER = 4;
  6. public static final int PASS_TEXT_LABEL = 5;
  7. public static final int PASS_SELECTION_LABEL = 6;
  8. public static final int PASS_VIDEO_LABEL = 7;
  9. public static final int PASS_LOCATION_LABEL = 8;
  10. public static final int PASS_MEDIASET_SOURCE_LABEL = 9;
Java代码  
  1. drawDisplayItem(view, gl, displayItem, texture, PASS_THUMBNAIL_CONTENT, placeholder,displayItem.mAnimatedPlaceholderFade); 画缩略图的,注掉此句,前两屏只显示框,第三屏OK
  2. drawDisplayItem(view, gl, displayItem, texture, PASS_FOCUS_CONTENT, null, 0.0f);画单张图片的,注掉,第三屏黑屏
  3. drawDisplayItem(view, gl, itemDrawn, textureToUse, PASS_FRAME, previousTexture, ratio);画边框的,注掉,前两屏明显没有边框,巨齿明显
  4. drawDisplayItem(view, gl, displayItem, textureString, PASS_TEXT_LABEL, null, 0);画文本标签的
  5. drawDisplayItem(view, gl, displayItem, textureToUse, PASS_SELECTION_LABEL, null, 0);画选中标记的
  6. drawDisplayItem(view, gl, displayItem, videoTexture, PASS_VIDEO_LABEL, null, 0);画视频标记的
  7. drawDisplayItem(view, gl, displayItem, locationTexture, PASS_LOCATION_LABEL, null, 0);画位置标记的
  8. drawDisplayItem(view, gl, displayItem, locationTexture, PASS_MEDIASET_SOURCE_LABEL,transparentTexture, 0.85f);画源来源图标的(相机或一般文件夹)

二、特效
举如何显示一张图片为例,在图片完全显示出来经过这样一个过程,附近的图片渐小渐出,当前图片渐大渐入,当前图片逐渐变大直到全屏。实现这个特效,要进行很多帧的渲染。就是说并不是只调一次onDrawFrame函数就可以了,要调用多次。可以把这个特效的实现想成一个状态变化的过程,在每一个状态,纹理的显示大小和位置都不同,这也符合动画的基本原理。放大、缩小我们只要改变顶点数据就可以做到,gallery3d也是这样做的,下面是主要代码:
我们知道调用onDrawFrame来渲染,最后调到下面的drawFocusItems函数,

Java代码  
  1. GridQuad quad = GridDrawables.sFullscreenGrid[vboIndex];
  2. float u = texture.getNormalizedWidth();
  3. float v = texture.getNormalizedHeight();
  4. float imageWidth = texture.getWidth();
  5. float imageHeight = texture.getHeight();
  6. boolean portrait = ((theta / 90) % 2 == 1);
  7. if (portrait) {
  8. viewAspect = 1.0f / viewAspect;
  9. }
  10. quad.resizeQuad(viewAspect, u, v, imageWidth, imageHeight);//改变用来贴图片的长方形的大小
  11. quad.bindArrays(gl);//绑定新数据,为渲染做准备。

而位置的改变有两种方式,一种是直接以顶点数据中改变,另一种是计算出在3维3个方向的偏移量,再调用gltranslate来做,从代码可以看出采用的是第二种方式来做的,比第一种方式更方便一些。代码:

Java代码  
  1. gl.glTranslatef(-translateXf, -translateYf, -translateZf);

而这里的3个偏移量的计算是和camera相关的,相关文件为GridCamera.java,GridCameraManager.java,过程很复杂,理清楚后再细化吧。

cache管理
下面是cache文件

Java代码  
  1. /sdcard/Android/data/com.cooliris.media/cache/local-album-cache
  2. d---rwxr-x system   sdcard_rw          2010-05-21 09:56 local-album-cache
  3. d---rwxr-x system   sdcard_rw          2010-05-21 09:56 local-meta-cache
  4. ----rwxr-x system   sdcard_rw   299877 2010-05-28 07:36 local-album-cachechunk_0
  5. d---rwxr-x system   sdcard_rw          2010-05-21 09:56 geocoder-cache
  6. ----rwxr-x system   sdcard_rw      284 2010-05-28 07:36 local-album-cacheindex
  7. d---rwxr-x system   sdcard_rw          2010-05-21 09:56 local-image-thumbs
  8. d---rwxr-x system   sdcard_rw          2010-05-21 09:56 local-video-thumbs
  9. d---rwxr-x system   sdcard_rw          2010-05-21 09:56 picasa-thumbs
  10. ----rwxr-x system   sdcard_rw       80 2010-05-28 07:36 local-meta-cachechunk_0
  11. ----rwxr-x system   sdcard_rw      164 2010-05-28 07:36 local-meta-cacheindex
  12. d---rwxr-x system   sdcard_rw          2010-05-21 09:56 hires-image-cache
  13. ----rwxr-x system   sdcard_rw   627629 2010-05-28 07:37 local-image-thumbschunk_0
  14. ----rwxr-x system   sdcard_rw     3914 2010-05-21 09:56 local-image-thumbsindex
  15. ----rwxr-x system   sdcard_rw    53343 2010-05-28 07:34 hires-image-cache-4982941342287215583_1024.cache
  16. ----rwxr-x system   sdcard_rw   237692 2010-05-28 07:33 hires-image-cache3684568484369117627_1024.cache
  17. ----rwxr-x system   sdcard_rw   133182 2010-05-28 07:34 hires-image-cache607542544081226432_1024.cache
  18. ----rwxr-x system   sdcard_rw    83223 2010-05-28 07:34 hires-image-cache4275479623210216146_1024.cache
  19. ----rwxr-x system   sdcard_rw   292837 2010-05-28 07:34 hires-image-cache-646316556936433937_1024.cache
  20. ----rwxr-x system   sdcard_rw   191377 2010-05-28 07:35 hires-image-cache2631364604509958174_1024.cache
  21. ----rwxr-x system   sdcard_rw   366905 2010-05-28 07:35 hires-image-cache-3280562009766080884_1024.cache
  22. ----rwxr-x system   sdcard_rw   323671 2010-05-28 07:35 hires-image-cache5752471827533329222_1024.cache

创建cache的关键代码

Java代码  
  1. LocalDataSource
  2. public static final DiskCache sThumbnailCache = new DiskCache("local-image-thumbs");----------------------local-image-thumbs local-image-thumbschunk_0  local-image-thumbsindex
  3. public static final DiskCache sThumbnailCacheVideo = new DiskCache("local-video-thumbs");--------------------local-video-thumbs
  4. public static final DiskCache sAlbumCache = new DiskCache("local-album-cache");----------------------local-album-cache  local-album-cacheindex
  5. public static final DiskCache sMetaAlbumCache = new DiskCache("local-meta-cache");------------------local-meta-cache  local-meta-cacheindex
  6. getChunkFile --------------local-meta-cachechunk_0  local-album-cachechunk_0
  7. ReverseGeocoder::  private static final DiskCache sGeoCache = new DiskCache("geocoder-cache"); -------------------------geocoder-cache
  8. PicasaDataSource:: public static final DiskCache sThumbnailCache = new DiskCache("picasa-thumbs");-----------------------------picasa-thumbs
  9. UriTexture::writeToCache  --------------------------hires-image-cache-xxx_1024.cache

布局补充:
在画一个界面是,是分类化的,比如第一个界面是显示所有有图片的文件夹,在代码里叫专辑.有这些元素要创建:
文本标签  显示专辑名和专辑内图片或视频数
路径条 显示路径名
按纽 拍照按纽,放大/缩小
菜单栏 全选,取消全选,分享,删除,更多等
图片边框
用于显示图片的矩形
在渲染时一次把一类元素画完,再画另一类.如主界面顺序为:
路径条->按纽->文本标签->图片边框->图片.
具体代码见drawBlendedComponents函数

1.CacheService.java中写缓存:sAlbumCache.put(ALBUM_CACHE_LOCALE_INDEX, sDummyData, 0);

第一个是key,这里是正常数据,当然还有别的key,key分别是-1,-2,-3,-4,-5。

2.DiskCache.java中,执行上面的写的过程,这里先得明白他的cache怎么装的:

它是由很多称之为“片”的文件组成的,形成一个List形式:private final

LongSparseArray<RandomAccessFile> mChunkFiles = new LongSparseArray<RandomAccessFile>();

即mChuckFiles就是整个cache,里面包括很多chunk(即片),每一个chunk大小为1MB.

当要写入某一个chunk里面的时候,先要找到他在mChuckFiles里面的索引值即chunkIndex,由

mChunkFiles.get(chunkIndex);来获取这个文件,chunkIndex怎么来的呢?

private LongSparseArray<Record> mIndexMap;

Record record = mIndexMap.get(key);这里的key就是上面用put方法传过来的

ALBUM_CACHE_LOCALE_INDEX的值(就是-5)

int chunkIndex = record.chunk;

这么一步步来的。

当然了,第一次都是空的,也就是get不到东西mChunkFiles.get(chunkIndex);和Record record =

mIndexMap.get(key);都get不到,那么第一次就先把东西放进去,mIndexMap.put(key, new Record

(chunkIndex, record.offset, data.length, record.sizeOnDisk, timestamp));(记录key值)以及 final

String chunkFilePath = mCacheDirectoryPath + CHUNK_FILE_PREFIX + chunk; chunkFile = new

RandomAccessFile(chunkFilePath, "rw");mChunkFiles.put(chunk, chunkFile);(三句代码来新建一个

chunkfile并放到cache列表里面)

注意:Record是内部类,只是一个数据集合类而已,相当于文件描述信息。每个cache(即chunk)对应一个。

private final LongSparseArray<RandomAccessFile> mChunkFiles = new LongSparseArray<RandomAccessFile>(); 中mChunkFiles最大装13个,每个chunk是1M,所以全部Cache是13M.

转载自:http://yueguc.iteye.com/blog/749205
nbsp;imageHeight

Gallery3D简介相关推荐

  1. android系列:第一篇 android开发常用命令集合,代码目录简介

    下面整理了android开发常用命令集合如adb命令,adb over wifi,jgrep等代码搜索命令,编译环境变量配置,lunch平台选择,mm模块编译,godir代码路径跳转,log.v()等 ...

  2. etcd 笔记(01)— etcd 简介、特点、应用场景、常用术语、分布式 CAP 理论、分布式原理

    1. etcd 简介 etcd 官网定义: A highly-available key value store for shared configuration and service discov ...

  3. Docker学习(一)-----Docker简介与安装

    一.Docker介绍 1.1什么是docker Docker是一个开源的应用容器引擎,基于Go语言并遵从Apache2.0协议开源 Docker可以让开发者打包他们的应用以及依赖包到一个轻量级,可移植 ...

  4. 【Spring】框架简介

    [Spring]框架简介 Spring是什么 Spring是分层的Java SE/EE应用full-stack轻量级开源框架,以IOC(Inverse Of Control:反转控制)和AOP(Asp ...

  5. TensorRT简介

    TensorRT 介绍 引用:https://arleyzhang.github.io/articles/7f4b25ce/ 1 简介 TensorRT是一个高性能的深度学习推理(Inference) ...

  6. 谷粒商城学习笔记——第一期:项目简介

    一.项目简介 1. 项目背景 市面上有5种常见的电商模式 B2B.B2C.C2B.C2C.O2O B2B 模式(Business to Business),是指商家和商家建立的商业关系.如阿里巴巴 B ...

  7. 通俗易懂的Go协程的引入及GMP模型简介

    本文根据Golang深入理解GPM模型加之自己的理解整理而来 Go协程的引入及GMP模型 一.协程的由来 1. 单进程操作系统 2. 多线程/多进程操作系统 3. 引入协程 二.golang对协程的处 ...

  8. Linux 交叉编译简介

    Linux 交叉编译简介 主机,目标,交叉编译器 主机与目标 编译器是将源代码转换为可执行代码的程序.像所有程序一样,编译器运行在特定类型的计算机上,输出的新程序也运行在特定类型的计算机上. 运行编译 ...

  9. TVM Operator Inventory (TOPI)简介

    TOPI简介 这是 TVM Operator Inventory (TOPI) 的介绍.TOPI 提供了比 TVM 具有更高抽象的 numpy 风格的,通用操作和调度.TOPI 如何在 TVM 中,编 ...

  10. 计算机视觉系列最新论文(附简介)

    计算机视觉系列最新论文(附简介) 目标检测 1. 综述:深度域适应目标检测标题:Deep Domain Adaptive Object Detection: a Survey作者:Wanyi Li, ...

最新文章

  1. ni visa pci_CHINACOAT 2019“推荐品牌”赫普菲乐|PCI可名文化出品
  2. PHP+redis实现超迷你全文检索
  3. linux调用一个函数失败 打印错误,linux系统调用出错时的处理函数
  4. sql查询百分之20到百分之40的数据_数据库基础学习——SQL语言知识总结(6)
  5. jeecg t:datagrid标签 每页显示条数 扩展
  6. 解释如何优化css选择器_购物车解释了CSS选择器
  7. html浮动之后怎么隐藏,div浮动之后排在一行,在把浮动去掉,把div用display设置成inline-block之后就不能排在一行了。...
  8. 怎么判断子元素距离父元素顶部位置_css子元素如何相对父元素定位?
  9. JavaScript基本数据类型
  10. python中的复数虚部_python复数的虚部怎么表达
  11. wps插入尾注(罗马数字变阿拉伯数字,即i变1)的操作方法
  12. Comparator.comparing排序使用示例
  13. 中国农业生物多样性危机-农业大健康·蒋高明:谋定生态安全
  14. [数据可视化] 图表设计原则
  15. element+后台管理系统数据导出为excel+进度条导出
  16. php Memcache/Memcached操作手册
  17. 纸牌游戏梭哈设计制作(C语言)
  18. Python自动化办公:将文本文档内容批量分类导入Excel表格
  19. 淘宝客对接遇到的坑!
  20. 基于matlab_simulink的捷联惯性导航系统仿真,基于MATLABSimulink的捷联惯性导航仿真.pdf...

热门文章

  1. win10ltsc安装后重启提示bitlocker有问题怎么办_原神安装运行问题-原神打不开进不去解决教程...
  2. 数字电子技术基础-2-逻辑函数的最小项与最大项
  3. 【Java爬虫】接口模拟微信公众号登录,搜索公众号,获取公众号文章,java实现
  4. 破解版的ABBYY FineReader OCR文字识别软件,真的好用吗?
  5. 数学建模方法自己归纳总结(建模参考用,包含相应例题以及MATLAB代码)
  6. python pip下载安装一半退出_Python- 解决PIP下载安装时因为网络速度慢而导致失败的方法...
  7. 经典算法——五大常用算法
  8. PHP 获取微视无水印源地址_PHP快速实现解析无水印播放地址URL——快手篇
  9. Java中StringBuffer类的常用方法
  10. android sonar 简书,Sonar使用指南