【原始碼剖析】Launcher 8.0 原始碼 (9) --- Launcher 啟動流程 第四步之桌面佈局(1)
本篇講解Launcher的oncreate的第四步setupViews();生成桌面佈局,進行事件的繫結等,這裡把setupViews();方法分為三步來講解。以setupViews()方法中的setupOverviewPanel();為分界線,以上為第一步,以下為第三步。
setupViews,方法第一部分
第一部分原始碼為
mDragLayer = (DragLayer) findViewById(R.id.drag_layer); mFocusHandler = mDragLayer.getFocusIndicatorHelper(); mWorkspace = mDragLayer.findViewById(R.id.workspace); mWorkspace.initParentViews(mDragLayer); mLauncherView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_LAYOUT_STABLE); // Setup the drag layer mDragLayer.setup(this, mDragController, mAllAppsController); // Setup the hotseat mHotseat = (Hotseat) findViewById(R.id.hotseat); if (mHotseat != null) { mHotseat.setOnLongClickListener(this); }
接下來我們就一步一步進行分析。
1.mDragLayer = (DragLayer) findViewById(R.id.drag_layer);
setupViews方法是在Launcher的oncreate中直接呼叫,所以我們可以得出結論是setupView方法在Launcher中,通過讀取res佈局檔案來找到各個UI控制元件,這裡是建立了重要的DragLayer,所有操作基本都是在這個佈局裡面進行的。
2.mFocusHandler = mDragLayer.getFocusIndicatorHelper();
這裡通過DrayLayer來獲取FocusIndicatorHelper,FocusIndicatorHelper是用於處理Focus的類,也就是焦點,android裡面的focus是指UI介面,當前處理的物件一般不會被感知到也不用處理focus,我們能感知到focus的是editText,當前焦點在輸入框時,輸入框會有游標,其實我們點選的任何一個元件時,都會有焦點鎖定到該元件上,這樣就可以理解為什麼focus會放到Draglayer裡面了,方便進行事件的處理。例如Launcher中有程式碼“favorite.setOnFocusChangeListener(mFocusHandler)。
3. mWorkspace = mDragLayer.findViewById(R.id.workspace);
獲取Workspace,建立workspace的物件,桌面放圖示的地方由workspace和hotseat兩部分組成,我們將hotseat稱作快捷欄,它在螢幕下方,用於放一些不隨“頁面”滑動變化的固定圖示。頁面就是我們說的workspace。
workspace的父類是pagedView,由多個可以滑動的頁面組成,PagedView的父類是ViewGroup,PagedView的子類是workspace和FolderPagedView,即Launcher利用ViewGroup做了一套放置圖示且可以通過滑動改變當前展示頁的類,這個類我們用在了桌面和資料夾中。
4. mWorkspace.initParentViews(mDragLayer);
public void initParentViews(View parent) { super.initParentViews(parent); mPageIndicator.setAccessibilityDelegate(new OverviewAccessibilityDelegate()); }
這個方法裡面呼叫了mPageIndicator.setAccessibilityDelegate方法,這裡呼叫的是View的setAccessibilityDelegate方法,因為PageIndicator繼承FramLayout,FramLayout繼承ViewGroup,ViewGroup又繼承View,這裡自定義了AccessibilityDelegate(OverviewAccessibilityDelegate()),來處理一些點選事件,
點進OverviewAccessibilityDelegate可以看到,裡面定義了點選OVERVIEW ,WALLPAPERS,WIDGETS,SETTINGS事件。
AccessibilityDelegate主要用來對View做一個檢測和處理,包括View的點選選中,滑動,touch,文字變化等等。
5.通過Flag設定螢幕狀態
mLauncherView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
對系統UI進行了Flag設定。
全屏:View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
隱藏導航欄: View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
狀態列:View.SYSTEM_UI_FLAG_LAYOUT_STABLE
6. mDragLayer.setup(this, mDragController, mAllAppsController);
把DragLayer與DragController,AllAppsController進行繫結,這樣,點選拖拽模組就完成了框架層的搭建。
7. mHotseat = (Hotseat) findViewById(R.id.hotseat);
建立Hotseat物件,並且為它設定長按點選事件。