转载 androidGallery3D源码分析 gallery2源码分析

原文地址:androidGallery3D源码分析作者:android小鸟

一、布局
gallery3d的界面生成和普通的应用程序不一样。普通程序一般一个界面就是一个activity,布局用xml或代码都可以实现,界面切换是activity的切换方式;而gallery3d没有用android的UI系统,而是用opengl画出来的,即界面是在同一个activity的,如主界面,缩略图界面,单张图片查看界面,标记界面等都属于同一个activity。

Ø重要线程推荐
在利用过程中有三个极其重要的线程存在:主线程(Gallery随activity的生命周期启用烧毁)、MediaFeed初始化线程(进去过程时只运行顺次,用于加载相册初始消息)、MediaFeed监听线程(始终在跑,监听相册和相片的改变),其中MediaFeed初始化线程的工作是:调用MediaFeed的loadMediaSets加载相册,MediaFeed监听线程MediaFeed.run()的工作是:依据“内容改变监听器“归来的媒体改变消息(增删改),继续不时的更新MediaFeed中的相册和相片变量。

那么这界面布局不同的界面是如何组合到一起的呢?分析代码,可以把它看成一个状态机

1、标记模式public static final int MODE_SELECT =1;(HudLayer)
包含了主界面标记模式,缩略界面矩阵游览时标记模式、缩略图界面分类游览时标记模式3个界面
2、普通模式public static final intMODE_NORMAL = 0;(HudLayer)
包含了
public static final intSTATE_MEDIA_SETS = 0;主界面
public static final intSTATE_GRID_VIEW = 1;缩略图矩阵浏览
public static final intSTATE_FULL_SCREEN = 2;查看界面
public static final intSTATE_TIMELINE = 3;缩略图界面分类浏览

Ø切换界面流程
相册界面,缩略图界面,以及图片博览界面等,这些界面的跳转不同于activity之间的跳转,因为它们并不是每个都对应一个独自的activity而是分享一个activity。Gallery3D里面用不同的事态来标识不同的界面,这些事态定义在GridLayer里面如下:
public static final int STATE_MEDIA_SETS = 0;
public static final int STATE_GRID_VIEW = 1;
public static final int STATE_FULL_SCREEN = 2;
public static final int STATE_TIMELINE = 3;
事态的改变引起界面的改变,Gallery3D里面批准了通知形式,事态改变的接口为GridLayer中的public voidsetState(--int state),通知接口为HudLayer中的public voidonGridStateChanged()。界面的切换是由事件发动的,因而在事件的响应函数里面会对用户的触屏动作分解成一个个的事态,如刚进去Gallery3D的时候会穿越调用setState(STATE_MEDIA_SETS)设置事态为STATE_MEDIA_SETS,并发送通知即调用onGridStateChanged()最后调用HudLayer的updateViews()措施举行描摹与更新,从而进去相册界面;同样当用户点击相册的时候,会改换事态为STATE_GRID_VIEW,然后重新描摹界面进去缩略图界面,其他界面的切换也是同样的理由,当事态未曾发生改变的时候将不会厉行回调函数setState()和onGridStateChanged()。

有了以上状态分类后,在渲染的时候就能根据些界面的组成来定哪些控件譔隐藏,哪些要显示了。
下面是基本控件:
com.cooliris.media.GridLayer :网格所略图揭示和个体图片揭示
com.cooliris.media.BackgroundLayer:背景
com.cooliris.media.HudLayer:相册揭示
com.cooliris.media.ImageButton:图片按钮(重要指进去Gallery后右上角的那个控件)
com.cooliris.media.TimeBar:进去Gallery后下方可拖动的悬浮控件
com.cooliris.media.MenuBar :点击图片时弹出的菜单按钮

com.cooliris.media.PopupMenu:点击菜单按钮后弹出来的菜单项
com.cooliris.media.PathBarLayer:现今Gallery后左上方揭示图片路径的空间
在渲染时,每一帧所有界面上的元素都画了,由于根据上面的状态只把特定窗口的特定元素显示出来,其它窗口中的隐藏,所以不会乱。
Layer是上面控件的基类,上面控件的类也就有了下面两个方法来隐藏不譔显示的界面元素。
public boolean isHidden(){
returnmHidden;
}

public void setHidden(booleanhidden) {
if (mHidden!= hidden) {
mHidden =hidden;
onHiddenChanged();
}
}
下面是根据上面分类来画不同元素所用的标识:
public static final intPASS_THUMBNAIL_CONTENT = 0;
public static final intPASS_FOCUS_CONTENT = 1;
public static final intPASS_FRAME = 2;
public static final intPASS_PLACEHOLDER = 3;
public static final intPASS_FRAME_PLACEHOLDER = 4;
public static final intPASS_TEXT_LABEL = 5;
public static final intPASS_SELECTION_LABEL = 6;
public static final intPASS_VIDEO_LABEL = 7;
public static final intPASS_LOCATION_LABEL = 8;
public static final intPASS_MEDIASET_SOURCE_LABEL = 9;

drawDisplayItem(view, gl, displayItem, texture,PASS_THUMBNAIL_CONTENT, placeholder,
displayItem.mAnimatedPlaceholderFade);画缩略图的,注掉此句,前两屏只显示框,第三屏OK
drawDisplayItem(view, gl, displayItem, texture, PASS_FOCUS_CONTENT,null, 0.0f);画单张图片的,注掉,第三屏黑屏
drawDisplayItem(view, gl, itemDrawn, textureToUse, PASS_FRAME,previousTexture, ratio);画边框的,注掉,前两屏明显没有边框,巨齿明显
drawDisplayItem(view, gl, displayItem, textureString,PASS_TEXT_LABEL, null, 0);画文本标签的
drawDisplayItem(view, gl, displayItem, textureToUse,PASS_SELECTION_LABEL, null, 0);画选中标记的
drawDisplayItem(view, gl, displayItem, videoTexture,PASS_VIDEO_LABEL, null, 0);画视频标记的

drawDisplayItem(view, gl, displayItem, locationTexture,PASS_LOCATION_LABEL, null, 0);画位置标记的
drawDisplayItem(view, gl, displayItem, locationTexture,PASS_MEDIASET_SOURCE_LABEL,
transparentTexture, 0.85f);画源来源图标的(相机或一般文件夹)

Ø渲染流程
Gallery3D的渲染从 RenderView 开始。RenderView 从 GLSu***ceView继承而来,批准了通知型描摹形式,即穿越调用requestRender 通知 RenderView 重绘屏幕。RenderView将所有必需描摹的对象都保留一个 Lists中,Lists 包括了5个ArrayList,其定义如下所示:
public final ArrayList<Layer>updateList =newArrayList<Layer>();
public final ArrayList<Layer>opaqueList =newArrayList<Layer>();
public final ArrayList<Layer>blendedList =newArrayList<Layer>();
public final ArrayList<Layer>hitTestList =newArrayList<Layer>();
public final ArrayList<Layer>systemList = newArrayList<Layer>();

RenderView 的onDrawFrame接口告终每一帧的描摹垄断,描摹时遍历 lists 里每个 list 的每一个成员并调用其renderXXX 函数。重要代码如下所示:
...
final Lists lists = sLists;

final ArrayList<Layer> updateList =lists.updateList;
boolean isDirty = false;
for (int i = 0,imomc.com size = updateList.size(); i != size;++i) {
boolean retVal =updateList.get(i).update(this,mFrameInterval);
isDirty |= retVal;
}
if (isDirty) {
requestRender();
}

// Clear the depth buffer.
gl.glClear(GL11.GL_DEPTH_BUFFER_BIT);
gl.glEnable(GL11.GL_SCISSOR_TEST);
gl.glScissor(0, 0, getWidth(), getHeight());

// Run the opaque pass.
gl.glDisable(GL11.GL_BLEND);
final ArrayList<Layer> opaqueList =lists.opaqueList;
for (int i = opaqueList.size() - 1; i >= 0; --i){
final Layer layer = opaqueList.get(i);
if (!layer.mHidden) {
layer.renderOpaque(this,gl);
}
}

// Run the blended pass.
gl.glEnable(GL11.GL_BLEND);
final ArrayList<Layer> blendedList =lists.blendedList;
for (int i = 0, size = blendedList.size(); i != size; ++i) {
final Layer layer = blendedList.get(i);
if (!layer.mHidden) {
layer.renderBlended(this,gl);
}
[转载]androidGallery3D源码分析 gallery2源码分析
}
gl.glDisable(GL11.GL_BLEND);

lists 的各个 list 里包括的各个 layer 如下所示:
lists
|-----------------------|-----------------------|-----------------------|-----------------------|
updateListopaqueList blendedList systemListhitTestList
| ||| |
GridLayerGridLayer GridLayerGridLayerGridLayer
BackgroudLayerBackgroudLayer BackgroudLayer
HudLayerHudLayerHudLayer HudLayer
TimeBarTimeBar TimeBar
PathBar PathBar PathBar
XXXButton XXXButtonXXXButton
XXXMenuXXXMenuXXXMenu
Layer供给了update(....),renderOpaque(....),renderBlended(....)接口,这些接口会在RenderView的onDrawFrame描摹代码中被调用。GridLayer中有个GridDrawManager,专程负责描摹,在前面的那几个接口中会调用到GridDrawManager的一些翔实描摹函数告终恳挚的画图工作如:
drawDisplayItem(view, gl, displayItem, texture,PASS_THUMBNAIL_CONTENT,placeholder,displayItem.mAnimatedPlaceholderFade); 画缩略图的
drawDisplayItem(view, gl, displayItem, texture, PASS_FOCUS_CONTENT,null,0.0f);画单张图片的
drawDisplayItem(view, gl, itemDrawn, textureToUse, PASS_FRAME,previousTexture,ratio);画边框的
drawDisplayItem(view, gl, displayItem, textureString,PASS_TEXT_LABEL, null,0);画文本标签的
drawDisplayItem(view, gl, displayItem, textureToUse,PASS_SELECTION_LABEL,null, 0);画选中符号的
drawDisplayItem(view, gl, displayItem, videoTexture,PASS_VIDEO_LABEL, null,0);画视频符号的
drawDisplayItem(view, gl, displayItem, locationTexture,PASS_LOCATION_LABEL,null, 0);画位置符号的
drawDisplayItem(view, gl, displayItem, locationTexture,PASS_MEDIASET_SOURCE_LABEL,transparentTexture,0.85f);画源起源图标的(相机或等闲文件夹)

Ø事件机制
由于所有界面都同属于一个activity,因而所有的事件引发动作都起源于主线程,切实上是主线程中的RenderView的onTouchEvent:
public boolean onTouchEvent(MotionEvent event) {
// Ignore events received before thesu***ce is created toavoid
// deadlocking with GLSu***ceView'sneedToWait().
if (mGL == null) {
returnfalse;
}
// Wait for the render thread toprocess this event.
if (mTouchEventQueue.size() >8&& event.getAction() ==MotionEvent.ACTION_MOVE)
return true;
synchronized (mTouchEventQueue) {
MotionEventeventCopy = MotionEvent.obtain(event);
mTouchEventQueue.addLast(eventCopy);
requestRender();
}
return true;
}
在这里它将所有的触屏事件放在一个待处理的事件队列里面,当队列里面的事件数大于8可能该事件属于拖动事件的时候它将期待,否则会将该事件加入队列,并调用requestRender()哀求描摹。于是会重新调用RenderView的onDrawFrame描摹代码,其中有个函数processTouchEvent(),这个函数的重要功能是负责处理事件队列中的事件,查找该事件起源于哪个控件(对应翔实的某个Layer子类),然后将事件发放给该控件处理,控件接受到事件的时候会调用切身的onTouchEvent()函数,在这里会依据事件的不同设置一些不同的数据重要是给描摹的时候要用的,最后会调用到恳挚的事件处理类GestureDetector.Java的相干措施包括对是否是双击阿单击阿等。在这里必需解释一下,它并未曾把响应事件的翔实告终放在每个layer的子类中,而是提取出了一个类GestureDetector.Java专程负责响应事件。以上即便全副事件的响应流程,事件统一由RenderView负责创立,然后依据条件的不同下发给相应的控件响应


二、特效
举如何显示一张图片为例,在图片完全显示出来经过这样一个过程,附近的图片渐小渐出,当前图片渐大渐入,当前图片逐渐变大直到全屏。实现这个特效,要进行很多帧的渲染。就是说并不是只调一次onDrawFrame函数就可以了,要调用多次。可以把这个特效的实现想成一个状态变化的过程,在每一个状态,纹理的显示大小和位置都不同,这也符合动画的基本原理。放大、缩小我们只要改变顶点数据就可以做到,gallery3d也是这样做的,下面是主要代码:
我们知道调用onDrawFrame来渲染,最后调到下面的drawFocusItems函数,
GridQuad quad = GridDrawables.sFullscreenGrid[vboIndex];
float u = texture.getNormalizedWidth();
float v = texture.getNormalizedHeight();
float imageWidth = texture.getWidth();
float imageHeight = texture.getHeight();
boolean portrait = ((theta / 90) % 2 == 1);
if (portrait) {
viewAspect =1.0f / viewAspect;
}
quad.resizeQuad(viewAspect, u, v, imageWidth,imageHeight);//改变用来贴图片的长方形的大小
quad.bindArrays(gl);//绑定新数据,为渲染做准备。
而位置的改变有两种方式,一种是直接以顶点数据中改变,另一种是计算出在3维3个方向的偏移量,再调用gltranslate来做,从代码可以看出采用的是第二种方式来做的,比第一种方式更方便一些。代码:
gl.glTranslatef(-translateXf, -translateYf, -translateZf);
而这里的3个偏移量的计算是和camera相关的,相关文件为GridCamera.java,GridCameraManager.java,过程很复杂,理清楚后再细化吧。

cache管理
下面是cache文件
/sdcard/Android/data/com.cooliris.media/cache/local-album-cache
d---rwxr-x systemsdcard_rw 2010-05-2109:56 local-album-cache
d---rwxr-x systemsdcard_rw 2010-05-2109:56 local-meta-cache
----rwxr-x systemsdcard_rw299877 2010-05-28 07:36local-album-cachechunk_0
d---rwxr-x systemsdcard_rw 2010-05-2109:56 geocoder-cache
----rwxr-x systemsdcard_rw 2842010-05-28 07:36 local-album-cacheindex
d---rwxr-x systemsdcard_rw 2010-05-2109:56 local-image-thumbs
d---rwxr-x systemsdcard_rw 2010-05-2109:56 local-video-thumbs
d---rwxr-x systemsdcard_rw 2010-05-2109:56 picasa-thumbs
----rwxr-x systemsdcard_rw 802010-05-28 07:36 local-meta-cachechunk_0
----rwxr-x systemsdcard_rw 1642010-05-28 07:36 local-meta-cacheindex
d---rwxr-x systemsdcard_rw 2010-05-2109:56 hires-image-cache
----rwxr-x systemsdcard_rw627629 2010-05-28 07:37local-image-thumbschunk_0
----rwxr-x systemsdcard_rw39142010-05-21 09:56 local-image-thumbsindex
----rwxr-x systemsdcard_rw 53343 2010-05-28 07:34hires-image-cache-4982941342287215583_1024.cache
----rwxr-x systemsdcard_rw237692 2010-05-28 07:33hires-image-cache3684568484369117627_1024.cache
----rwxr-x systemsdcard_rw133182 2010-05-28 07:34hires-image-cache607542544081226432_1024.cache
----rwxr-x systemsdcard_rw 83223 2010-05-28 07:34hires-image-cache4275479623210216146_1024.cache
----rwxr-x systemsdcard_rw292837 2010-05-28 07:34hires-image-cache-646316556936433937_1024.cache
----rwxr-x systemsdcard_rw191377 2010-05-28 07:35hires-image-cache2631364604509958174_1024.cache
----rwxr-x systemsdcard_rw366905 2010-05-28 07:35hires-image-cache-3280562009766080884_1024.cache
----rwxr-x systemsdcard_rw323671 2010-05-28 07:35hires-image-cache5752471827533329222_1024.cache
创建cache的关键代码
LocalDataSource
public static final DiskCache sThumbnailCache = newDiskCache("local-image-thumbs");----------------------local-image-thumbslocal-image-thumbschunk_0local-image-thumbsindex
public static final DiskCache sThumbnailCacheVideo = newDiskCache("local-video-thumbs");--------------------local-video-thumbs
public static final DiskCache sAlbumCache = newDiskCache("local-album-cache");----------------------local-album-cachelocal-album-cacheindex
public static final DiskCache sMetaAlbumCache = newDiskCache("local-meta-cache");------------------local-meta-cachelocal-meta-cacheindex
getChunkFile--------------local-meta-cachechunk_0local-album-cachechunk_0

ReverseGeocoder::private staticfinal DiskCache sGeoCache = new DiskCache("geocoder-cache");-------------------------geocoder-cache
PicasaDataSource:: public static final DiskCache sThumbnailCache =newDiskCache("picasa-thumbs");-----------------------------picasa-thumbs
UriTexture::writeToCache--------------------------hires-image-cache-xxx_1024.cache

欢迎大家多交流,不对之处请大家指正。

  

爱华网本文地址 » http://www.413yy.cn/a/25101014/233539.html

更多阅读

转载 SuperMap拓扑分析 网络拓扑结构分析

Good~原文地址:SuperMap拓扑分析作者:云海冲浪的鱼拓扑关系是地理对象在空间位置上的相互关系,如节点与线、线与面之间的连接关系,空间实体之间的拓扑关系是GIS进行空间分析和决策的基础之一,是否具有高效、可靠的拓扑处理功能已成为衡量

转载 鬼道子技术分析课文---如果爆!!! 鬼道子

原文地址:鬼道子技术分析课文---如果爆!!!作者:鬼道子其实本来不想写的,但是很多人感觉恍惚了,所以就写一下,而且本人会用两个如果,这里的如果是对走势结构的理解,不参杂任何辩解成分。因为观点本人还是曾经的观点。首先:本人的数字因子结构计

转载 湘源控规的使用 湘源控规使用教程

原文地址:湘源控规的使用作者:liuqiaoxiong一、高程分析或者坡度分析的面积统计问题1、ft命令回车 命令行:选择参照块(即在图例上选择一个色块)回车2、命令行:构造实体集类型[0-同层实体 1-同类实体 2-同层及同类实体 3-同色实体]<3>选

声明:《转载 androidGallery3D源码分析 gallery2源码分析》为网友瘋爺分享!如侵犯到您的合法权益请联系我们删除