Gallery2中的view显示

来源:互联网 发布:mysql 转换字符串 编辑:程序博客网 时间:2024/05/18 02:07

首先GalleryActivity.java里面设置setContentView(R.layout.main); 该布局里面有一个GLRootView, 该类继承自GLSurfaceView。所以整个界面的内容的显示是在GLSurfaceView上的。该类的用法框架如下:

mSurfaceView = new GLSurfaceView(this);setContentView(mSurfaceView );mSurfaceView.setRenderer(new Renderer() {@Overridepublic void onSurfaceCreated(GL10 gl, EGLConfig config) {Log.e(TAG, "onSurfaceCreated");}@Overridepublic void onSurfaceChanged(GL10 gl, int width, int height) {Log.e(TAG, "onSurfaceChanged");}@Overridepublic void onDrawFrame(GL10 gl) {Log.e(TAG, "onDrawFrame");}});

只要在GLSurfaceView里设置一个GLSurfaceView.Renderer接口的类即可通过监听来在GLSurfaceView界面上通过onDrawFrame画出图像来。

还需要设置渲染模式setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);此时通过GLSurfaceView的requestRender()方法即可回调onDrawFrame画出每一帧。

在图库中根界面是GLRootView,它实现接口GLRoot。所有它上面的视图都继承自GLView。

下面以AlbumPage页面为例说明显示过程。

AlbumPage相当于一个Activity,它的父类中有真正Activity(GalleryActivity)的实例,并且它能通过该Activity获得在GalleryActivity中的布局GLRootView。

在AlbumPage类中,首先实例化了一个类GLView mRootPane =new GLView();该类重写了父类的onLayout和render。

在AlbumPage的onCreate的initializeViews方法中又实例化了一个view(SlotView),并将它加入mRootView中:mRootPane.addComponent(mSlotView);

进入GLView中的addComponent方法可以看到它做了几件事。

public void addComponent(GLView component) {        // Make sure the component doesn't have a parent currently.        if (component.mParent != null) throw new IllegalStateException();        // Build parent-child links        if (mComponents == null) {            mComponents = new ArrayList<GLView>();        }        mComponents.add(component);        component.mParent = this;        // If this is added after we have a root, tell the component.        if (mRoot != null) {            component.onAttachToRoot(mRoot);        }}

第一建了个ArrayList,并把加入的子view放入该arraylist中,然后设置该子view的父亲为this。最后通过component.onAttachToRoot(mRoot);将mRoot设到子view中。

接着在onResume中setContentPane(mRootPane);


protected void setContentPane(GLView content) {        mContentPane = content;        if (mIntroAnimation != null) {            mContentPane.setIntroAnimation(mIntroAnimation);            mIntroAnimation = null;        }        mContentPane.setBackgroundColor(getBackgroundColor());        mActivity.getGLRoot().setContentPane(mContentPane);    }

进入到ActivityState中可以看到,这个时候设置mContentPane的背景颜色,并调用mActivity.getGLRoot().setContentPane(mContentPane);将mContentPane设到GLRootView中。

进入到GLRootView的setContentPane方法中

public void setContentPane(GLView content) {        if (mContentView == content) return;        if (mContentView != null) {            if (mInDownState) {                long now = SystemClock.uptimeMillis();                MotionEvent cancelEvent = MotionEvent.obtain(                        now, now, MotionEvent.ACTION_CANCEL, 0, 0, 0);                mContentView.dispatchTouchEvent(cancelEvent);                cancelEvent.recycle();                mInDownState = false;            }            mContentView.detachFromRoot();            BasicTexture.yieldAllTextures();        }        mContentView = content;        if (content != null) {            content.attachToRoot(this);            requestLayoutContentPane();        }    }

这里,如果新设置的跟视图与原来的相同直接返回。如果不同,但原来的不为空,先要把原来的跟视图detachFromRoot。让它的mRoot为空,遍历所有子视图,将子视图的mRoot都设为空。这时将新的跟视图设到GLRootView中。并attachToRoot,将该根视图的mRoot置为GLRootView。接下来requestLayoutContentPane()。顾名思义调用布局根视图的方法。后面的调用流程如下图所示:

GLRootView      requestLayoutContentPane

                                      |

                                     V

GLRootView      requestRender

                                      |

                                     V

GLSurfaceView   requestRender

                                      |

                                     V

GLRootView      onDrawFrame

                                      |

                                     V

GLRootView      onDrawFrameLocked

                                      |                                                         |

                                     V                                                        V

GLRootView      layoutContentPane              mContentView.render()

                                     |                                                          |

                                    V                                                         V

GLRootView      mContentView.layout();   调用mContentView子view的render

后面需要再次要求layout和render的主要途径有两个:

对每个view进行invalidate或者requestLayout。

Invalidate会调用GLRootView的requestRender。

requestLayout会调用GLRootView的requestLayoutContentPane。


0 0
原创粉丝点击