浏览器探究——APP层UI布局
http://blog.csdn.net/hxwwf/article/details/7798016
最外层的布局
最外层的View是Activity的mActivity.getWindow().getDecorView(),显示为PhoneWindow$DecorView
它的内部有FrameLayout为id/content,通过FrameLayout frameLayout = (FrameLayout) mActivity.getWindow().getDecorView().findViewById(android.R.id.content);获取到。
接下来获取activity的LayoutInflater,通过LayoutInflater.from(mActivity)
然后利用inflate载入layout的xml。
LayoutInflater.from(mActivity).inflate(R.layout.custom_screen,frameLayout);
这样把custom_screen.xml中的布局内容加入为frameLayout(即id/content)的子layout。
custom_screen.xml中的布局
在custom_screen.xml中定义了2个并列级别的布局:id/fullscreen_custom_content(FrameLayout),id/vertical_layout(LineraLayout)
其中id/fullscreen_custom_content中主要是布局了NavScreen,而id/vertical_layout中主要布局了WebView。
在id/vertical_layout中又定义了并列的两个布局:id/error_consol(LinearLayout),id/main_content(FrameLayout)
在BaseUi中成员变量:
FrameLayout mContentView;对应了id/main_content(FrameLayout)
FrameLayout mCustomViewContainer;对应了id/fullscreen_custom_content(FrameLayout),
LinearLayout mErrorConsoleContainer;对应了id/error_consol(LinearLayout)
TitleBar的布局
接下来创建了一个TitleBar对象,TitleBar继承自RelativeLayout,通过
LayoutInflater factory =LayoutInflater.from(context);
factory.inflate(R.layout.title_bar, this);
把title_bar.xml中的布局加入到自己中。那么看下title_bar.xml中定义的布局
首先外层是一个id/titlebar(RelativeLayout),在id/titlebar内部又有id/taburlbar(NavigationBarPhone:NavigationBarBase: LinearLayout),id/snapshotbar_stub (ViewStub),id/autologin_stub (ViewStub),id/progress(PageProgressView:ImageView)
上述的四个布局在TitleBar类中分别对应以下成员:
NavigationBarBase mNavBar;
SnapshotBar mSnapshotBar;
AutologinBar mAutoLogin;
private PageProgressView mProgress;
其中mSnapshotBar与mAutoLogin是通过inflateSnapshotBar()与inflateAutoLoginBar()函数动态加载出的。
NavigationBarPhone 布局
NavigationBarPhone对应的布局文件是title_bar_nav.xml
该文件中得到如下的布局
由该布局可见,很多ImageButton默认是不显示的,只有需要时再显示,即实际上几个Image位于同样的显示位置,根据不同的状态选择显示不同的ImageButton,比如在地址栏输入url时,网站icon的id/iconcombo就不显示。
经过了上述的描述。知道了TitleBar的布局,但是TitleBar如何与之前的id/main_content
关联上的呢?并且这里还缺少了WebView这个核心控件。
回顾一下TitleBar是在BaseUi构造时创建的。而此时并没有创建WebView。
在Controller:: createNewTab中创建了Tab并通过BaseUi::setActiveTab把WebView加入到布局中。
Tab中WebView的布局
Tab中有两个主要的成员
// Main WebView wrapper
private View mContainer; //这个是WebView的外层的布局view
// Main WebView
private WebView mMainView;
Tab的构造函数中会通过Tab::setWebView为自身添加一个WebView控件。
Tab::setWebView会进一步调用Controller::onSetWebView,Controller::onSetWebView又会进一步调用BaseUi::onSetWebView,在BaseUi:: onSetWebView中会初始化Tab:: mContainer。
Tab:: mContainer对应了tab.xml中的布局。该布局中有个id/webview_wrapper(FrameLayout),Tab::mMainView会被设置给id/webview_wrapper(FrameLayout),作为它的子View。
Tab的布局如下:
id/main_content(FrameLayout)与Tab布局与TitleBar布局的关联
至次,已经有了id/main_content(FrameLayout),又有了这个Tab布局,还有一个TitleBar布局。接下来是他们三个的连接。
在BaseUi::attachTabToContentView(Tab tab)中,会把Tab:: mContainer设置为BaseUi::mContentView的子View,这样id/main_content(FrameLayout)就与Tab布局关联上了。
在PhoneUi:: setActiveTab(final Tab tab)中,会调用WebView::setEmbeddedTitleBar,并把TitleBar对象作为参数传入。
WebView:: setEmbeddedTitleBar(View v),把TitleBar设置为WebView的子View,这样Tab布局就与TitleBar布局关联上了。
这样得到如下的布局
多窗口页面的布局
上述是对于正常浏览网页的布局,接下来看下在多窗口页面的布局情况。当前打开了3个Tab,然后进入到多窗口页面中。
回到最上面看下id/content(FrameLayout),它的一个子viewid/vertical_layout _content(LineraLayout) 即上述的浏览网页时的布局。另一个子viewid/fullscreen_custom_content(FrameLayout)则是显示多窗口时的布局。那么接下来就看下显示多窗口时,它旗下的布局是怎样的。
在BaseUi中id/fullscreen_custom_content(FrameLayout)对应成员protectedFrameLayout mCustomViewContainer;
在PhoneUi中会创建一个NavScreen(RelativeLayout)对象,并把它设置为mCustomViewContainer的子view。NavScreen(RelativeLayout)对应的就是多窗口页面的布局。这样就把多窗口页面与id/fullscreen_custom_content(FrameLayout)关联上了。
NavScreen的布局
NavScreen本身继承自RelativeLayout,其初始化时加载了nav_screen.xml布局为其子view。如下代码
LayoutInflater.from(mContext).inflate(R.layout.nav_screen,this);
加载了nav_screen.xml中的布局后如下
id/scroller(NavTabScroller)是多窗口图片预览的布局。
NavTabScroller的布局
NavTabScroller继承自ScrollerView。其内部又创建了一个类ContentLayout,它是继承自LinearLayout。NavTabScroller初始化时会创建ContentLayout并把ContentLayout设置为它的子view。
ContentLayout根据屏幕的旋转方向可以选择水平或垂直布局。
NavTabScroller中有成员BaseAdaptermAdapter;用于记录添加进NavTabScroller:: ContentLayout中的子view的列表。
在NavScreen中会创建TabAdapter并把它设置给NavTabScroller。
TabAdapter中提供的View就是一个个的NavTabView,被TabAdapter组织起来,在把TabAdapter设置给NavTabScroller,NavTabScroller::ContentLayout会取出NavTabView并设置为自己的子View。
NavTabView本身是集成自LinearLayout的。每个NavTabView对应一个Tab。由于NavTabScroller中管理了NavTabView,那么也可以进一步的获取到每个Tab的信息。这里主要需要取出Tab的截图以及网址信息等。
到了这里可以看到多窗口页面的图片显示区最外层轮廓是一个ScrollerView,这样就可以滑动的看到里面的一个个Tab的截图了。
里面是一个个的NavTabView。
NavTabView的布局
NavTabView的初始化时会加载nav_tab_view.xml的布局,并设置为自身的子View。
LayoutInflater.from(mContext).inflate(R.layout.nav_tab_view,this);
加载后的布局如下:
多窗口页面整体布局
综合以上可得多窗口的整体布局如下