【Launcher2源碼解讀】Launcher中的自定義控件

本文對Launcher2進行一個全面的瞭解,介紹Launcher2中的自定義控件java

如圖:android



launcher.xmlapp

<?xml version="1.0" encoding="utf-8"?>
<com.callmewill.launcher2.DragLayer xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:launcher="http://schemas.android.com/apk/res/com.callmewill.launcher2"
    android:id="@+id/drag_layer"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@drawable/workspace_bg" >    //最外層的自定義佈局繼承FrameLayout,主要功能手指拖動時生成一個懸浮的view,以及各類位值計算

    <include
        android:id="@+id/dock_divider"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom"
        android:layout_marginBottom="@dimen/button_bar_height"
        layout="@layout/workspace_divider" />        //底部指示器的背景

    <include
        android:id="@+id/paged_view_indicator"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom"
        android:layout_marginBottom="@dimen/button_bar_height"
        layout="@layout/scroll_indicator" />         //底部指示器

    <!-- The workspace contains 5 screens of cells -->

    <com.callmewill.launcher2.Workspace              //繼承PagedView,SmoothPagedView,實現一個ViewGroup內部有多個View而且左右滑動
        android:id="@+id/workspace"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:paddingBottom="@dimen/workspace_bottom_padding"
        android:paddingLeft="@dimen/workspace_left_padding"
        android:paddingRight="@dimen/workspace_right_padding"
        android:paddingTop="@dimen/workspace_top_padding"
        launcher:cellCountX="@integer/cell_count_x"
        launcher:cellCountY="@integer/cell_count_y"
        launcher:defaultScreen="2"
        launcher:pageSpacing="@dimen/workspace_page_spacing"
        launcher:scrollIndicatorPaddingLeft="@dimen/workspace_divider_padding_left"
        launcher:scrollIndicatorPaddingRight="@dimen/workspace_divider_padding_right" >

        <include
            android:id="@+id/cell1"
            layout="@layout/workspace_screen" />     //內部的子View,主要類是CellLayout,CellLayout是一個網格的自定義ViewGroup,用來裝各類item

        <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.callmewill.launcher2.Workspace>

    <include                                         //底部的Dock欄
        android:id="@+id/hotseat"
        android:layout_width="match_parent"
        android:layout_height="@dimen/button_bar_height_plus_padding"
        android:layout_gravity="bottom"
        layout="@layout/hotseat" />

    <include
        android:id="@+id/qsb_bar"                    //頂部的搜索和移目標控件
        layout="@layout/qsb_bar" />

    <com.callmewill.launcher2.DrawableStateProxyView  //app抽屜,一樣繼承PagedView
        android:id="@+id/voice_button_proxy"
        android:layout_width="80dp"
        android:layout_height="@dimen/qsb_bar_height"
        android:layout_gravity="top|right"
        android:clickable="true"
        android:onClick="onClickVoiceButton"
        launcher:sourceViewId="@+id/voice_button" />

    <include
        android:id="@+id/apps_customize_pane"       //app抽屜,一樣繼承PagedView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        layout="@layout/apps_customize_pane"
        android:visibility="invisible" />

    <include
        android:id="@+id/workspace_cling"           //用戶引導
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        layout="@layout/workspace_cling"
        android:visibility="gone" />

    <include
        android:id="@+id/folder_cling"               //用戶引導
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        layout="@layout/folder_cling"
        android:visibility="gone" />

</com.callmewill.launcher2.DragLayer>



從上往下說吧ide

搜索條:點擊搜索條時調用的系統自己的SearchManager來完成相關邏輯,Launcher.java 中的startGlobleSearch方法:佈局

public void startGlobalSearch(String initialQuery, boolean selectInitialQuery, Bundle appSearchData, Rect sourceBounds) {
		final SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
		ComponentName globalSearchActivity = searchManager.getGlobalSearchActivity();
		if (globalSearchActivity == null) {
			Log.w(TAG, "No global search activity found.");
			return;
		}
		Intent intent = new Intent(SearchManager.INTENT_ACTION_GLOBAL_SEARCH);
		intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
		intent.setComponent(globalSearchActivity);
		// Make sure that we have a Bundle to put source in
		if (appSearchData == null) {
			appSearchData = new Bundle();
		} else {
			appSearchData = new Bundle(appSearchData);
		}
		// Set source to package name of app that starts global search, if not
		// set already.
		if (!appSearchData.containsKey("source")) {
			appSearchData.putString("source", getPackageName());
		}
		intent.putExtra(SearchManager.APP_DATA, appSearchData);
		if (!TextUtils.isEmpty(initialQuery)) {
			intent.putExtra(SearchManager.QUERY, initialQuery);
		}
		if (selectInitialQuery) {
			intent.putExtra(SearchManager.EXTRA_SELECT_QUERY, selectInitialQuery);
		}
		intent.setSourceBounds(sourceBounds);
		try {
			startActivity(intent);
		} catch (ActivityNotFoundException ex) {
			Log.e(TAG, "Global search activity not found: " + globalSearchActivity);
		}
	}


DragLayer.javaspa

——FrameLayoutcode


Workspace.java  手指滑動,在多個屏幕之間切換

——ViewGroupxml

        ——PagedView                內部View跟隨手指滑動繼承

  ——SmoothPagedView  處理滑動時的速度圖片

        ——Workspace                 完成內容的展現


CellLayout.java  在Workspace中,和Hotseat中,是一個網格狀的控件,能夠設置行列,span,用來顯示app,widget,shortcut,folder等

——ViewGroup


AppCustomsizeTabHost.java

——TabHos    t抽屜內部的Tab標籤


AppCustomsizePagedView

——ViewGroup

        ——PagedView 

        ——DragItemPagedVIew  手提內拖拽app到Workspace


Folder.java   展現文件夾內部內容的View,內部包含一個CellLayout

——LinearLayout 


FolderIcon.java 文件夾縮略圖

——LinearLayout


BubbleTextView.java 用來顯示app,shortcut

——TextView

textView.setCompoundDrawablesWithIntrinsicBounds(left,top,right,bottom)給TextView設置上下左右四個圖片


PagedViewIcon.java 抽屜內部顯示icon

——TextView 


Hotseat.java 底部的Dock欄

—— FrameLayout


PagedViewWidget.java  抽屜內部顯示Widget

——LinearLayout


AppWidgetResizeFrame.java 重置Widget大小時的指示框

——FrameLayout


LauncherAppWidgetHost.java 顯示加載Widget有關

——AppWidgetHost


每一個控件的代碼量都很大,看起來也費時費力。

相關文章
相關標籤/搜索