Preference组件探究之Base,Support及AndroidX对比

简介: 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。

1832b220aa754cd18c504acc7686a560.png

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

1832b220aa754cd18c504acc7686a560.png

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。

1832b220aa754cd18c504acc7686a560.png

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,估计应该也是差不多的。

1832b220aa754cd18c504acc7686a560.png

抛开一些注释和微小的代码优化,AndroidX果真只是针对Support包的简单整合。

我们将Base包,Support包及AndroidX包下的Preference做下总结。

Base VS Support VS AndroidX

1672144177885.png

Base包的Preference使用的ListView在性能表现,内存占用,扩展支持等方面已经落后于RecyclerView。在经历了9大版本之后即将谢幕,交棒给AndroidX。


虽然将被弃用,但其实现思路,公开API和使用文档深深地影响了Support包的Preference的设计。在Android平台上的设置模块它是当之无愧的元老。其关于Preference的设计理念也被Support和AndroidX很好地继承和发扬。


让我们一起感谢android.preference的付出,欢迎androidx.preference的到来!


--------------------------------------------------------------------------------------------------------------------------------------------------------------


20200304更新


android Q的時候frameworks/support的源碼已經從AOSP倉庫的主分支(master)裏移動到了androidx分支(androidx-master-dev),參考如下提交。


https://android-review.googlesource.com/c/platform/prebuilts/sdk/+/896475

Import Support Library, AndroidX from build 5280039


prebuilts/sdk/current/androidx-README.md文件裏可以看到説明。

如果需要查看的源碼的話,在prebuilts/sdk/current/androidx下搜索-sources.jar命名的jar包。

比如recyclerview的代碼為recyclerview-1.1.0-alpha07-sources.jar。參與編譯的為recyclerview-1.1.0-alpha07.aar。

如果需要修改代碼的話,需要切到androidx-master-dev倉庫去貢獻代碼。


這種變化使得想要在源碼裏修改support邏輯變得困難。

取得源碼自行編譯后得到class文件替換prebuilts下面的aar文件或許可行。。。


--------------------------------------------------------------------------------------------------------------------------------------------------------------



相关文章
|
3月前
|
JSON Android开发 C++
Android c++ core guideline checker 应用
Android c++ core guideline checker 应用
|
3月前
|
JSON Android开发 数据格式
Android c++ core guideline checker 应用问题之JSON compilation database的定义如何解决
Android c++ core guideline checker 应用问题之JSON compilation database的定义如何解决
|
Android开发 开发者 UED
Android Design Support Library初探-更新中
Android Design Support Library初探-更新中
98 0
|
Android开发
【错误记录】Android Studio 编译报错 ( AppCompat does not support the current theme features )
【错误记录】Android Studio 编译报错 ( AppCompat does not support the current theme features )
295 0
【错误记录】Android Studio 编译报错 ( AppCompat does not support the current theme features )
|
Android开发
Android中gradle文件中implementation和compile的异同
相同之处:都是为Module添加依赖 不同之处:implementation不可以依赖传递,但是compile可以依赖传。这是什么意思呢?有经验的开发人员基本上都了解,举个例子,如果一个App依赖于libA,libA又依赖...
1327 0
|
容器 Go API
01.源码阅读(Fragment--support-fragment-26.0.0-alpha1)
往一个viewgroup中添加fragment的两种方式如下: FragmentManager fragmentManager = getSupportFragmentManager(); FragmentTransaction fragmentTransaction = fragmentManager.
918 0
|
Android开发 数据格式 XML
Android Design Support Library全解:Part 5 CoordinatorLayout 与其他控件的联动
Android Design Support Library系列第5弹,TabLayout 实现滑动选项卡 1504424076347.png 在前文Part 4 – TabLayout中我们已经使用CoordinatorLayout和其他控件配合过(比如Snackbar出现时,FAB上移),这里来重点介绍其使用方法。
1268 0
|
Android开发 容器 Java
Android Design Support Library全解:Part 4 TabLayout 实现滑动选项卡
Android Design Support Library系列第4弹,TabLayout 实现滑动选项卡 智能管家Tablayout.gif 如上图的滑动选项卡的效果在移动端的应用中很是常见,之前要是该效果需要利用动态加载布局技术和控制滑动技术(比如利用HorizontalScrollView),较为繁琐。
1400 0
|
Android开发
Android Design Support Library全解:Part 2 Snackbar
Android Design Support Library系列第2弹: Snackbar “Providing lightweight, quick feedback about an operation is a perfect opportunity to use a snackbar.
861 0