转载请注明出处: 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类。