Android 7.0 Gallery图库源码分析6 - 完成界面渲染

本文详细解析了Gallery图库的源码,从SlotView的渲染准备开始,深入探讨了界面更新过程,包括GLRootView的请求渲染机制、OpenGLES的绘制流程,直至最终在界面上呈现每个专辑的具体实现。
摘要由CSDN通过智能技术生成

转载请注明出处: http://blog.csdn.net/lb377463323/article/details/70275971

这里接着Gallery图库源码分析3的SlotView渲染准备完成后讲解,前面讲了当数据准备完成后,通过mListener.onContentChanged()通知界面更新。mListener就是AlbumSetSlotRenderer的MyCacheListener。

    //也就是SlotView刷新界面
    public void onContentChanged() {
            mSlotView.invalidate();
    }

    //root即为GLRootView,它是继承自GLSurfaceView
    public void invalidate() {
        GLRoot root = getGLRoot();
        if (root != null) root.requestRender();
    }

root.rerequestRender就是请求渲染一帧数据,之后走到Renderer的onDrawFrame方法

    public void onDrawFrame(GL10 gl) {
       //每绘制一帧都会回调此方法,也就是说你想绘制三角形还是纹理贴图等都是在这方法里面实现。
        try {
            //这个方法是实际绘制界面的
            onDrawFrameLocked(gl);
        } finally {
            mRenderLock.unlock();
        }
    }

接着看下onDrawFrameLocked方法

    private void onDrawFrameLocked(GL10 gl) {
        ......
        //mContentView就是AlbumSetPage
        if (mContentView != null) {
           mContentView.render(mCanvas);
        } else {
        ......
    }

AlbumSetPage的render方法调用其父类GLView的render方法

    protected void render(GLCanvas canvas) {
            ......
            super.render(canvas);
            canvas.restore();
        }

GLView的render方法主要是对其自控件进行渲染

    protected void render(GLCanvas canvas) {
        ......
        for (int i = 0, n = getComponentCount(); i < n; ++i) {
            renderChild(canvas, getComponent(i));
        }

    protected void renderChild(GLCanvas canvas, GLView component) {
        ......
        //这里component就是SlotView,用于绘制每个专辑
        component.render(canvas);
        ......
    }

接着看SlotView的render方法

    protected void render(GLCanvas canvas) {
        ......
        for (int i = mLayout.mVisibleEnd - 1; i >= mLayout.mVisibleStart; --i) {
                //renderItem就是对每一个专辑进行绘制
                int r = renderItem(canvas, i, 0, paperActive);
                if ((r & RENDER_MORE_FRAME) != 0) more = true;
                if ((r & RENDER_MORE_PASS) != 0) requestedSlot[requestCount++] = i;
            }
        ......
    }

    private int renderItem(
            GLCanvas canvas, int index, int pass, boolean paperActive) {
        ......
        //mRenderer就是AlbumSetSlotRenderer
        int result = mRenderer.renderSlot(
                canvas, index, pass, rect.right - rect.left, rect.bottom - rect.top);
        ......
    }

查看AlbumSetSlotRenderer到额renderSlot方法,这里就是绘制每个专辑的具体实现

    public int renderSlot(GLCanvas canvas, int index, int pass, int width, int height) {
        AlbumSetEntry entry = mDataWindow.get(index);
        int renderRequestFlags = 0;
        //绘制专辑显示的缩略图
        renderRequestFlags |= renderContent(canvas, entry, width, height);
        //绘制显示文件夹名称、数目、文件夹icon的Label
        renderRequestFlags |= renderLabel(canvas, entry, width, height);
        //绘制长按选择专辑时的蓝色图层
        renderRequestFlags |= renderOverlay(canvas, index, entry, width, height);
        return renderRequestFlags;
    }

最终所有专辑都通过canvas绘制出来,canvas是通过OpenGL ES的GLES20.glDrawArrays(type, 0, count)来绘制的,具体自行查看GLES20Canvas类。

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值