解决方案 1:本机PreferenceFragment
与AppCompatActivity
在 AndroidStudio 中,选择File > New Project >...> SettingsActivity。此模板使用一种变通方法,对原生进行改造PreferenceFragment
以使用AppCompatActivity
,类似于support.v4.Fragment
或support.v7.PreferenceFragmentCompat
.
- 优点:您现在可以在
AppCompat
应用程序中使用本机首选项功能。这是使用 AS 模板时的一种快速方法,您可以坚持现有的 Preference 文档和工作流程。
- 缺点:改造不是很直观或干净。此外,由于通常建议在可用的情况下使用支持库,因此我不确定这种方法是否具有前瞻性。
解决方案2:support.v7.preference.PreferenceFragmentCompat
使用AppCompatActivity
- 优点:最大限度地提高兼容性
- 缺点:有很多差距需要弥补。此外,这可能不适用于任何现有的偏好扩展库(例如
ColorPicker
或FontPreferences
)。
如果您选择不使用解决方案 1(我仍然不确定两者中哪一个更适合未来),使用support.v7.preference
.
下面提到了使用解决方案 2 的重要缺点。
依赖项:
dependencies {
...
compile 'com.android.support:appcompat-v7:23.1.1'
compile 'com.android.support:preference-v7:23.1.1'
compile 'com.android.support:support-v4:23.1.1'
}
主题:
您需要preferenceTheme
在您的styles.xml 中定义a,否则运行您的应用程序将引发异常。
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light">
<!-- Customize your theme here. -->
<item name="preferenceTheme">@style/PreferenceThemeOverlay</item>
</style>
您可能想将其拆分为 7+/14+/21+ 的不同样式。在撰写本文时,很多人抱怨这是错误的。这里有一个非常全面的答案。
行为变化:使用本机首选项非常简单:您需要做的就是定义/维护您的preferences.xml
并addPreferencesFromResource(R.xml.preferences)
在您的PreferenceFragment
. 自定义首选项可以通过子类轻松完成DialogPreference
,然后只需在preferences.xml
... bam 中引用即可。
不幸的是,support.v7.preference
已经Fragment
剥离了与处理相关的所有内容,使其失去了很多内置功能。您现在不仅要维护 XML,还必须继承和覆盖很多东西,不幸的是,所有这些东西都没有记录在案。
PreferenceScreens: PreferenceScreens
不再由框架管理。PreferenceScreen
在您的preference.xml
(如文档中所述)中定义 a将显示该条目,但单击它不会执行任何操作。现在由您来处理显示和导航子屏幕。无聊的。
有一种方法(在此处描述),将 a 添加PreferenceFragmentCompat.OnPreferenceStartScreenCallback
到您的PreferenceFragmentCompat
. 虽然这种方法可以快速实施,但它只是交换了现有偏好片段的内容。缺点是:没有后退导航,你总是“在顶部”,这对用户来说不是很直观。
在另一种方法中(在此处描述),您还必须管理后退堆栈以实现预期的后退导航。这preferenceScreen.getKey()
用作每个新创建/显示的片段的根。
这样做时,您可能还会偶然发现PreferenceFragments
默认情况下透明并奇怪地叠加在一起。人们倾向于覆盖PreferenceFragmentCompat.onViewCreated()
以添加类似
// Set the default white background in the view so as to avoid transparency
view.setBackgroundColor(ContextCompat.getColor(getContext(), R.color.background_material_light));
自定义 DialogPreference:制作自己的偏好也从琐碎变得无聊。DialogPreference
现在已经删除了处理实际对话框的任何内容。那一点现在住在PreferenceDialogFragmentCompat
. 因此,您必须对两者进行子类化,然后处理创建对话框并自己显示它(在此处解释)。
查看源代码PreferenceFragmentCompat.onDisplayPreferenceDialog()
表明它知道如何处理恰好 2 个对话框首选项(EditTextPreference
, ListPreference
),您必须使用OnPreferenceDisplayDialogCallback
s 自己实现的所有其他内容......一个奇迹,为什么没有处理子类的功能DialogPreference
!
以下是一些代码,它们实现了大多数这些变通方法并将它们装箱到 lib 模块中:
https://github.com/mstummer/extended-preferences-compat.git
主要意图是:
- 无需在每个应用程序/项目中扩展
Activity
和摆弄。现在再次成为唯一需要更改/维护的每个项目文件。PreferenceFragment
preference.xml
- 按预期处理和显示
PreferenceScreens
(子屏幕)。
- 取消拆分
DialogPreference
以恢复本机行为。
- 处理和显示
DialogPreference
.
不要认为它足够干净以至于开箱即用,但在处理类似问题时它可能会给你一些提示。试一试,如果您有任何建议,请告诉我。