Preference組件探究之Base,Support及AndroidX對比

Android提供的Preference組件使得APP設置頁面的開發變得簡單。
除了上述幾篇文章討論的Base包的Preference組件外,Android還提供了更爲高效的Support包的Preference組件。
甚至於即將發佈的Android Q預期將Support包的Preference組件全面替換爲AndroidX包的組件

本篇文章我們將探討這三種Preference組件。

從Android官網的描述我們知道,Base包的Preference組件自Android 1.0(API 1)開始引入,並於Android Q(API 29)變爲非推薦API。

Base包的Preference組件自打Android發佈來,效力了9大版本(Android 1 ~ 9),並將在Android 10(Android Q)被正式廢棄。 

雖然非推薦並非禁止使用,但是官方不再維護的組件,儘量遷移至替代組件還是比較明智的選擇。畢竟廢棄了的API指不定埋下什麼坑。

前面幾篇文章花不少時間闡述了Base包的Preference組件的使用方法,原理解讀和自定義方法。既然已經廢棄了,那麼這些探討是不是毫無用處了呢?我覺得也不盡然,不管Preference組件再怎麼變,其原理,使用方式不會差太大。
溫故可以知新。

Android官方給的替代組件是AndroidX包的Preference組件。

AndroidX本是Jetpack使用的開源框架,如今Google將Support包也整合了進來。
在講述AndroidX之前我們先介紹一下Support包下的Preference。

Support-Preference

 

Preference組件於版本24引入到了support V7中。

從官網的描述中我們知道support包採用RecyclerView控件展示PreferenceScreen上的組件。
使用性能更好的RecyclerView代替了ListView使得support包的Preference組件更爲高效。

V7

PreferenceFragmentCompat的源碼看得出來內部加載了RecyclerView控件。

// frameworks/support/v7/preference/src/android/support/v7/preference/PreferenceFragmentCompat.java
public abstract class PreferenceFragmentCompat extends Fragment … {
    public View onCreateView(…) {
        …
        final RecyclerView listView = onCreateRecyclerView(themedInflater, listContainer,
                savedInstanceState); // 默認加載了RecyclerView控件
        if (listView == null) {
            throw new RuntimeException("Could not create RecyclerView");
        }

        mList = listView;
        …
        return view;
    }
}

 Support包的PreferenceFragmentCompat除了提供像Base包一樣的addPreferencesFromResource()外還提供瞭如下方法。

setPreferencesFromResource()
定義:用於複寫指定key的PreferenceScreen。
原理:比addPreferencesFromResource()多了一個查找目標key的PreferenceScreen的過程。

onCreatePreferences()
定義:提供給子類複寫用來指定Preference佈局的抽象方法。
使用:子類複寫後可以調用addPreferencesFromResource()或setPreferencesFromResource()去加載佈局,也可以直接創建Preference組件後手動添加到PreferenceScreen。
原理:onCreate()的最後將默認調用這個抽象方法去執行子類的配置。

除了上述的PreferenceFragmentCompat如下網址顯示V7下面還有一大堆和Base包差不多名稱的Preference相關類,使用方法也大同小異。
https://developer.android.google.cn/reference/android/support/v7/preference/package-summary

其中有一個類需要關注下:PreferenceViewHolder。

PreferenceViewHolder是support-v7包下加入的RecyclerView$ViewHolder子類。
內部持有title,summary等Preference內控件,用於Preference組件下緩存RecyclerView元素。

PreferenceScreen通過PreferenceGroupAdapter和RecyclerView綁定。

PreferenceGroupAdapter#onCreateViewHoler()回調時將加載Preference佈局,得到itemView後封裝爲PreferenceViewHolder對象進行緩存。
並調用Preference#onBindViewHolder()進行初始化。
所以如果想自定義Support包的Preference組件的話需要複寫onBindViewHolder()。

除了V7,V14,V17包都含有Preference組件。

V14

新引入瞭如下組件。
SwitchPreference和V7-SwitchPreferenceCompat一樣,改了名字
PreferenceFragment     和V7-PreferenceFragmentCompat一樣,改了名字
PreferenceDialogFragment 帶Dialog的PreferenceFragment抽象基類
EditTextPreferenceDialogFragment 佈局爲輸入框的PreferenceDialogFragment
ListPreferenceDialogFragment 佈局爲列表選擇的PreferenceDialogFragment
MultiSelectListPreference 佈局爲列表選擇的DialogPreference
MultiSelectListPreferenceDialogFragment 佈局爲多選列表的PreferenceDialogFragment

V17

BaseLeanbackPreferenceFragment 類似瑞士軍刀風格leanback風格的PreferenceFragment抽象基類,內部集成了VerticalGridView控件
LeanbackPreferenceFragment 外層包裹了標題的BaseLeanbackPreferenceFragment子類
LeanbackSettingsFragment 根佈局爲LeanbackSettingsRootView的Fragment組件,主要和LeanbackPreferenceFragment配合使用
LeanbackPreferenceDialogFragment 帶DialogPreference的Fragment組件
LeanbackListPreferenceDialogFragment 帶List
Preference的LeanbackPreferenceDialogFragment組件

Android基於大屏幕設備推出了leanback導航模式並引入到了V17中,上述的Preference相關組件都是基於leanback風格的相應擴展組件。

 AndroidX

我們回到起初說到的替代組件:AndroidX包的Preference組件。
可以跟隨官方的如下說明將Support包遷移至AndroidX。

https://developer.android.google.cn/jetpack/androidx/migrate

 

如下網址展示了AndroidX所有的class列表。

https://developer.android.google.cn/reference/androidx/classes

Support-v7, v14下的Preference組件全部遷移到了androidx.preference包下。
Support-v17下的Preference組件全部遷移到了androidx.leanback.preference包下。

按照官方的說法。只是將Support包的代碼整合到了AndroidX中。實際是不是這樣呢?

AndroidX代碼是開源的。
AndroidX源碼網址:https://android.googlesource.com/platform/frameworks/support/+/androidx-master-dev

在Android系統的源碼目錄:frameworks/support/preference/src/main/java/androidx/preference/

 

Support VS AndroidX

將Support包和AndroidX包中最基礎的Preference類分別取出並diff。
 
經過diff我發現兩個java文件除了大量的格式,書寫風格的差異以外,代碼邏輯幾乎完全一致。
Preference以外的文件沒有diff,估計應該也是差不多的。


拋開一些註釋和微小的代碼優化,AndroidX果真只是針對Support包的簡單整合。

我們將Base包,Support包及AndroidX包下的Preference做下總結。

Base VS Support VS AndroidX
  Base Support AndroidX
引入 Andoid 1.0 Andoid 2.3 Andoid 10.0
棄用 Andoid 10.0 爲了兼容暫未棄用 -
包名 android.preference android.support.v7.preference
android.support.v14.preference
android.support.v17.preference
androidx.preference
androidx.leanback.preference
原理 採用ListView控件展示 採用RecyclerView控件展示 採用RecyclerView控件展示
源碼 frameworks/base/core/
java/android/preference/
frameworks/support/v7/preference/
frameworks/support/v14/preference/
frameworks/support/v17/preference-leanback/
frameworks/support/preference/
frameworks/support/leanback-preference

 

 

 

 

 

 

 

 

 

Base包的Preference使用的ListView在性能表現,內存佔用,擴展支持等方面已經落後於RecyclerView。在經歷了9大版本之後即將謝幕,交棒給AndroidX。

雖然將被棄用,但其實現思路,公開API和使用文檔深深地影響了Support包的Preference的設計。在Android平臺上的設置模塊它是當之無愧的元老。其關於Preference的設計理念也被Support和AndroidX很好地繼承和發揚。

讓我們一起感謝android.preference的付出,歡迎androidx.preference的到來!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章