Android N Settings模組與Android M Settings模組差異
Android N Settings 與之前的Android版本Settings模組在UI上右較大的改變,最直觀的差異在於Android N 設定介面增加了向右滑動的抽屜效果。
先回想下android M設定的主介面時怎麼顯示和互動的?
android M設定的主介面是定義在res/xml/dashboard_categories.xml這個檔案中,其SettingsActivity.java繼承與Activity,在其onCreate方法中,通過mIsShowingDashboard變數,控制載入不同的佈局R.layout.settings_main_dashboard或者
R.layout.settings_main_prefs
SettingsActivity.java中buildDashboardCategories()->loadCategoriesFromResource(R.xml.dashboard_categories,
categories, this) ->updateTilesList
對於二級選單,在設定模組中有一個Settings.java的類,該類中定義了許多直接繼承與SettingsActivity的空實現Activity,如果細心點還會發現,這些空實現的Activity在AndroidMainifest.xml中都有<meta-data/>屬性,這是為什麼呢?原因很簡單,上面說過,既然這些Activity都是繼承與SettingsActivity,那麼要啟動這些Activity時必然會走SettingsActivity
當然,並不是所有的設定項都是這樣,例如若要在Settings中新增一個選項,跳轉到其他應用中,那麼也可以直接在dashboard_categories.xml中新增相應的item,直接用intent跳轉過去也時可以的。
那麼,Android N中的設定主介面又時怎麼顯示和互動的呢?
Android N 在程式碼架構上和Android M最大的區別是Android N設定程式碼分為了兩部分,一部分是在packages/apps/Settings,另一部分是在frameworks/base/packages/SettingsLib。
Android N Settings增加了向右滑動的抽屜效果,即無論在一級二級還是三級選單介面下,只要向右滑動就可以調出Settings的主介面(事實上是無論哪一級選單,只要改級選單繼承了SettingsActivity,那麼就可以向右滑動調出設定的主介面)。接下來分析Android N Settings的啟動流程。
先看設定的入口類,Settings.java,該類和之前一樣,沒什麼變化,一樣繼承與SettingsActivity.java,內部也定義了很多空實現的內部類,空Activity繼承與SettingsActivity。那麼應該和android M一樣,真正的入口還是在SettingsActivity中。直接看SettingsActivity類,發現SettingsActivity不再是繼承與Activity類,而是繼承與rameworks/base/packages/SettingsLib下面的SettingsDrawerActivity,看一下SettingsDrawerActivity是什麼鬼??
SettingsDrawerActivity從名字來看,好像和實現滑動效果有關,到該類一看究竟,發現它載入的佈局時settings_with_drawer.xml,這個佈局中用到android.support.v4.widget.DrawerLayout,DrawerLayout 佈局就具有左右滑動的抽屜效果。在看settings_with_drawer.xml佈局中有一個listView控制元件,猜想該控制元件就是用來顯示抽屜佈局中的設定的主介面(後面在分析)。
繼續看SettingsActivity的onCreate方法,其載入佈局的地方和之前沒什麼區別,可是卻發現有區別的地方在從DashboardSummary.class中的獲取要載入item的資料部分,DashboardSummary.java的rebuildUI()中,呼叫了SettingsDrawerActivity的getDashboardCategories()獲取資料。也就是說在設定中主介面上要顯示那些選項也是rameworks/base/packages/SettingsLib中的SettingsDrawerActivity的getDashboardCategories()獲取來的,而不是像Android M一樣將佈局定義在res/xml/dashboard_categories.xml,現在在Settings模組下面已經沒有了dashboard_categories.xml檔案,那麼資料到底是怎麼獲取出來的呢?
現在來分析SettingsDrawerActivity類,在SettingsDrawerActivity的onCreate方法中,如上面提到,它載入的佈局是settings_with_drawer.xml,它是外層是DrawerLayout,所以能左右滑動(可自行百度DrawerLayout用法),該佈局中有listView,這個listView就是我們左右滑動看到的DrawerLayout的主介面,listView的Adapter是SettingsDrawerAdapter的例項,SettingsDrawerAdapter繼承於BaseAdapter,SettingsDrawerActivity中通過getDashboardCategories() >TileUtils.getCategories(this, sTileCache),獲取的資料,它將資料也是封裝成DashboardCategory型別。
再來看 TileUtils類的getCategories()是如何返回DashboardCategory物件的List的?先看程式碼:
getCategories()方法差不多可分為三步:
1.先呼叫getTilesForAction() ->getTilesForInten()從AndroidMainifast.xml中宣告的activity資訊中解析,並將解析的資料以Tile型別資料結構封裝。
2,遍歷儲存所有Tile的集合,將通過tile.category屬性,將其分類,並構建成category,並將category儲存在對應的categoryMap中。
3.構建categories,並且排序,排序是按照DashboardCategory的priority排序的。
先看一下Title資料型別,它裡面封裝的每一個變數都是和AndroidMainifast.xml中宣告Activity時<meta-data/>標籤一一對應的。
Title : 對應每個item顯示的標題
icon :對應每個Item顯示的圖示
summary : 對應每個item顯示的詳細資訊,summary
intent :item 對應的intent
cetagory :item 屬於哪一個catagory
priority : item 的位置有關,排序會用到
extras :Optional additional data for use by subclasses of the activity,從啟動它的類攜帶過來的資訊
meta-data :The metaData from the activity that defines this tile,定義的meta-data
通過這樣的方法獲取到了Settings主選單和左後滑動抽屜效果需要顯示的資料,然後將資料拋給SettingsDrawerAdapter,在它的getView方法中去建立對應的view,就將介面展示出來了。
總結一下:到了Android N設定中沒有主介面顯示的佈局檔案,而是直接解析AndroidManifast.xml檔案,從該檔案中獲得並處理要顯示的資訊。