当前位置: 代码迷 >> Android >> Android 2.3 Gallery3D增添gif支持——图片显示(二)
  详细解决方案

Android 2.3 Gallery3D增添gif支持——图片显示(二)

热度:98   发布时间:2016-05-01 13:03:17.0
Android 2.3 Gallery3D添加gif支持——图片显示(二)

       《Android 2.3 Gallery3D添加gif支持——概要(一)

       对于Gallery3D如何显示一张图片,请参看这位网友的Gallery3D笔记 。

       欢迎转载,请务必注明出处:http://blog.csdn.net/yihongyuelan

       在Gallery3D中,图片显示包括了缩略图和单张大图的显示,当我们点击缩略图时,会有一个动画效果,然后再显示大图片,如果显示图片较大,可能大图会先模糊一下然后再清晰显示。我们先来看看Gallery3D的基本结构,如图1:


                                                                            图1

       这是整个Gallery3D组成以及它们之间的关系。这有什么意义呢?回到我们本文的主旨图片显示:缩略图和大图。

        缩略图由Gallery3D中的CacheService创建,这些缩略图以Cache的方式存放在路径/mnt/sdcard/Android/data/com.cooliris.media/中。缩略图是显示在一个个固定宽高(在GridLayer中设定)的方框中,CacheService.getImageList从数据库中获取图片信息,CacheService.refresh()方法负责建立相册并把图片放到相册中。

       大图片的显示过程。在Android系统中,通过MediaScanner的扫描,会将扫描的媒体文件信息(路径,类型等等)存放到数据库中(/data/data/com.android.providers.media/databases/external.db),当用户点击缩略图时,触发界面重绘,同时会将该张缩略图的真实路径从数据库中获取出来,并调用图片解码器进行解码,最终返回到重绘后的界面。解析成功后的图片会以Cache的形式保存在SD卡中,再次加载速度就会更快了。

对于大图片的绘制,每一帧图片都会调用onDrawFrame来完成渲染,最终调用到GridDrawManager.java中的drawFocusItems()函数中。画单张图片最终调用的方法是drawDisplayItem(view, gl, displayItem, fsTexture, PASS_FOCUS_CONTENT, null, 1.0f);

       代码如下:

private void drawDisplayItem(RenderView view, GL11 gl, DisplayItem displayItem, Texture texture, int pass,            Texture previousTexture, float mixRatio) {        GridCamera camera = mCamera;        Vector3f animatedPosition = displayItem.mAnimatedPosition;        float translateXf = animatedPosition.x * camera.mOneByScale;        float translateYf = animatedPosition.y * camera.mOneByScale;        float translateZf = -animatedPosition.z;        int stackId = displayItem.getStackIndex();        final int maxDisplayedItemsPerSlot = (displayItem.mCurrentSlotIndex == mCurrentScaleSlot && mCurrentScaleSlot != Shared.INVALID) ? GridLayer.MAX_DISPLAYED_ITEMS_PER_FOCUSED_SLOT                : GridLayer.MAX_DISPLAYED_ITEMS_PER_SLOT;        if (pass == PASS_PLACEHOLDER || pass == PASS_FRAME_PLACEHOLDER) {            translateZf = -0.04f;        } else {            if (pass == PASS_FRAME)                translateZf += 0.02f;            if ((pass == PASS_TEXT_LABEL || pass == PASS_LOCATION_LABEL || pass == PASS_SELECTION_LABEL) && !displayItem.isAlive()) {                translateZf = 0.0f;            }            if (pass == PASS_TEXT_LABEL && translateZf > 0) {                translateZf = 0.0f;            }        }        boolean usingMixedTextures = false;        boolean bind = false;        if ((pass != PASS_THUMBNAIL_CONTENT)                || (stackId < maxDisplayedItemsPerSlot && texture.isLoaded() && (previousTexture == null || previousTexture                        .isLoaded()))) {            if (mixRatio == 1.0f || previousTexture == null || texture == previousTexture) {                bind = view.bind(texture);            } else if (mixRatio != 0.0f) {                if (!texture.isLoaded() || !previousTexture.isLoaded()) {                    // Submit the previous texture to the load queue                    view.bind(previousTexture);                    bind = view.bind(texture);                } else {                    usingMixedTextures = true;                    bind = view.bindMixed(previousTexture, texture, mixRatio);                }            } else {                bind = view.bind(previousTexture);            }        } else if (stackId >= maxDisplayedItemsPerSlot && pass == PASS_THUMBNAIL_CONTENT) {            mDisplayList.setAlive(displayItem, true);        }        if (!texture.isLoaded() || !bind) {            if (pass == PASS_THUMBNAIL_CONTENT) {                if (previousTexture != null && previousTexture.isLoaded() && translateZf == 0.0f) {                    translateZf = -0.08f;                    bind |= view.bind(previousTexture);                }                if (!bind) {                    return;                }            } else {                return;            }        } else {            if (pass == PASS_THUMBNAIL_CONTENT || pass == PASS_FOCUS_CONTENT) {                if (!displayItem.mAlive) {                    mDisplayList.setAlive(displayItem, true);                }            }        }        gl.glTranslatef(-translateXf, -translateYf, -translateZf);        float theta = (pass == PASS_FOCUS_CONTENT) ? displayItem.mAnimatedImageTheta + displayItem.mAnimatedTheta                : displayItem.mAnimatedTheta;        if (theta != 0.0f) {            gl.glRotatef(theta, 0.0f, 0.0f, 1.0f);        }        float orientation = 0.0f;        if (pass == PASS_THUMBNAIL_CONTENT && displayItem.mAnimatedImageTheta != 0.0f) {            orientation = displayItem.mAnimatedImageTheta;        }        if (pass == PASS_FRAME || pass == PASS_FRAME_PLACEHOLDER) {            GridQuadFrame.draw(gl);        } else {            GridQuad.draw(gl, orientation);        }        if (theta != 0.0f) {            gl.glRotatef(-theta, 0.0f, 0.0f, 1.0f);        }        gl.glTranslatef(translateXf, translateYf, translateZf);        if (usingMixedTextures) {            view.unbindMixed();        }    }

       小结

       本文只是一个总结性的笔记,并没有设计到代码的详细分析,对于Gallery3D的代码来讲,网上已经有网友比较详细的分析了,这里也就不再赘述。同时在Android 4.0中,Google并没有继续沿用Gallery3D,而是将自己之发布的Gallery进行了重写,也就是我们现在看到的Gallery2,并且弃用了Android 2.3中的Gallery3D(毕竟这是一个第三方的应用啊),所以在Android 4.0上许多东西都改变了。

  相关解决方案