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

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

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

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

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

Android 2.3 Gallery3D添加gif支持——图片显示(二)_第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上许多东西都改变了。

你可能感兴趣的:(Android 2.3 Gallery3D添加gif支持——图片显示(二))