Launcher workspace 分析
簡介
workspace,那有許多的廠商會定製自己的首頁,要麼在上面放置一些特殊的應用的widget,要麼就是放置一些應用的表徵圖,這些定製比較簡單的,但是怎麼放置本文會做一些簡介。如果在workspace上放置一些比較複雜的ui,怎麼來做了?那有的童鞋肯定會說用widget來做啊,大家都知道widget的實現都是放在對應的應用中,而且,widget只支援android sdk中簡單的ui布局元素,不允許也不支援開發人員重定義的ui元素,怎麼來實現本文會詳細告訴你。
簡單表徵圖定製
簡單的表徵圖定製,只需要在workspace的設定檔中添加即可。launcher中有一個叫default_workspace.xml的設定檔,用於配置預設的案頭應用的表徵圖、widget以及捷徑。其配置方式如下:
<appwidget launcher:packageName="com.changhong.controlcenter" launcher:className="com.changhong.controlcente.SmartControlCenterWidget" launcher:screen="0" launcher:x="0" launcher:y="3" launcher:spanX="4" launcher:spanY="1" /> <favorite launcher:packageName="com.android.camera" launcher:className="com.android.camera.Camera" launcher:screen="1" launcher:x="0" launcher:y="3" />
1)appwidget用於配置widget
launcher:packageName:配置對應應用的包名
launcher:className:應用對應的widget類
launcher:screen:workspace有5屏,widget所在的螢幕
launcher:x:表示x方向上起始位置,這裡的數字表示第幾格,這裡對於螢幕劃分成像excell表的格
launcher:y:表示y方向上起始位置
launcher:spanX:表示水平方向的寬
launcher:spanY:表示垂直方向的寬
2)favorite
放置應用的表徵圖,配置元素意思一樣
複雜介面定製
1)包含布局
對於上面的定製還不夠,這樣的定製只是小打小鬧,有些廠商如果需要在案頭上放置一個特別複雜的介面,這時我們該如何來做,甚至有人說我們需要將workspace改成win8風格的,那以上這些定製技術就不能滿足這些需求了。
該如何應對這些需求,首先我們希望對launcher的更改比較小,同時希望我們的代碼不和launcher的複雜邏輯柔和在一起。下面來看看我們隊workspace的聲明。
<com.android.launcher2.Workspace android:id="@+id/workspace" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingLeft="@dimen/workspace_left_padding" android:paddingRight="@dimen/workspace_right_padding" android:paddingTop="@dimen/workspace_top_padding" android:paddingBottom="@dimen/workspace_bottom_padding" launcher:defaultScreen="2" launcher:cellCountX="@integer/cell_count_x" launcher:cellCountY="@integer/cell_count_y" launcher:pageSpacing="@dimen/workspace_page_spacing" launcher:scrollIndicatorPaddingLeft="@dimen/qsb_bar_height" launcher:scrollIndicatorPaddingRight="@dimen/button_bar_height"> <include android:id="@+id/cell1" layout="@layout/workspace_screen1" /> <include android:id="@+id/cell2" layout="@layout/workspace_screen" /> <include android:id="@+id/cell3" layout="@layout/workspace_screen" /> <include android:id="@+id/cell4" layout="@layout/workspace_screen" /> <include android:id="@+id/cell5" layout="@layout/workspace_screen" /> </com.android.launcher2.Workspace>
這是在launcher.xml中聲明的,該布局檔案是launcher的布局檔案。我們說workspace一般包含5屏,這裡你可以看到,包含5個布局,都是workspace_screen.xml.每個布局就是我們看到的一屏。這裡注意了,既然每屏都是一個布局,為什麼我們不可以自訂自己的螢幕了。所以這裡將第一屏的布局檔案改成workspace_screen1。但是我們說每屏都被劃分成儲存格形勢的,所以如果你想保留這樣的功能,我們只需要在workspace_screen的布局檔案上進行修整。下面是我修改後的布局檔案workspace_screen1.xml
<com.android.launcher2.CellLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:launcher="http://schemas.android.com/apk/res/com.android.launcher" android:layout_width="wrap_content" android:layout_height="wrap_content" android:paddingLeft="@dimen/cell_layout_left_padding" android:paddingRight="@dimen/cell_layout_right_padding" android:paddingTop="0dp" android:paddingBottom="0dp" android:hapticFeedbackEnabled="false" launcher:cellWidth="@dimen/workspace_cell_width" launcher:cellHeight="@dimen/workspace_cell_height" launcher:widthGap="@dimen/workspace_width_gap" launcher:heightGap="@dimen/workspace_height_gap" launcher:maxGap="@dimen/workspace_max_gap" > <include android:id="@+id/cellcontents" layout="@layout/smarthome"/> </com.android.launcher2.CellLayout>
對比workspace_screen.xml你會發現其實我們只是包含了一個布局檔案進來,為什麼可以包含布局檔案因為我們的CellLayout是一個ViewGroup,很顯然它是可以包含子view的。
對於布局檔案我們可以進行自己的定製,這樣在複雜的介面,這裡你都可以去實現。
2)對於ui元素的處理
說道上面大家疑問了,我們可以像上面來包含我們的布局檔案,但有時候我們不僅僅局限與此,我門還需要對ui元素進行處理。
這時候我們在那去擷取這些ui元素。
launcher啟動的時候,看看它的主介面Launcher.java,它會初始化各個介面元素,workspace、hotseat、widget、allapp等介面,我們擷取的時機肯定是在這些ui元素載入完後擷取,否則會出現null 指標。
初始化是在setupViews()方法中完成的,以下代碼為證:
private void setupViews() { final DragController dragController = mDragController; mLauncherView = findViewById(R.id.launcher); mDragLayer = (DragLayer) findViewById(R.id.drag_layer); mWorkspace = (Workspace) mDragLayer.findViewById(R.id.workspace); mQsbDivider = findViewById(R.id.qsb_divider); mDockDivider = findViewById(R.id.dock_divider); mLauncherView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN); mWorkspaceBackgroundDrawable = getResources().getDrawable(R.drawable.workspace_bg); mBlackBackgroundDrawable = new ColorDrawable(Color.BLACK); // Setup the drag layer mDragLayer.setup(this, dragController); // Setup the hotseat mHotseat = (Hotseat) findViewById(R.id.hotseat); if (mHotseat != null) { mHotseat.setup(this); } // Setup the workspace mWorkspace.setHapticFeedbackEnabled(false); mWorkspace.setOnLongClickListener(this); mWorkspace.setup(dragController); dragController.addDragListener(mWorkspace); // Get the search/delete bar mSearchDropTargetBar = (SearchDropTargetBar) mDragLayer.findViewById(R.id.qsb_bar); // Setup AppsCustomize mAppsCustomizeTabHost = (AppsCustomizeTabHost) findViewById(R.id.apps_customize_pane); mAppsCustomizeContent = (AppsCustomizePagedView) mAppsCustomizeTabHost.findViewById(R.id.apps_customize_pane_content); mAppsCustomizeContent.setup(this, dragController); // Setup the drag controller (drop targets have to be added in reverse order in priority) dragController.setDragScoller(mWorkspace); dragController.setScrollView(mDragLayer); dragController.setMoveTarget(mWorkspace); dragController.addDropTarget(mWorkspace); if (mSearchDropTargetBar != null) { mSearchDropTargetBar.setup(this, dragController); } }
所以我們的介面的擷取放在該方法後面就可以了,後面的處理根據實際需要進行處理。