瀏覽器探究——APP層UI佈局

最外層的佈局

最外層的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加入到佈局中。

TabWebView的佈局

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);

加載後的佈局如下:


多窗口頁面整體佈局

綜合以上可得多窗口的整體佈局如下

文章轉載於:http://blog.csdn.net/hxwwf/article/details/7798016

發佈了1 篇原創文章 · 獲贊 21 · 訪問量 11萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章