android – 如何使用Support.v7.preference与AppCompat和潜在的缺点

我正在尝试使用support.v7.preference实现AppCompat应用程序的首选项.由于support.v7.preference与本机偏好有一些显着的差异,所以我花了几天的时间来弄清楚,一旦你知道这不是太糟糕,但不幸的是,在那里没有什么文件.我以为我会分享我的发现,所以其他人不必经历同样的痛苦.

所以问题:

如何最好地实现AppCompat应用程序的首选项(PreferenceFragment和AppCompatAcitivity不兼容)?

以下是几个相关问题:

> Preference sub-screen not opening when using support.v7.preference
> How to move back from Preferences subscreen to main screen in PreferenceFragmentCompat?
> PreferenceFragmentCompat requires preferenceTheme to be set
> How do I create custom preferences using android.support.v7.preference library?

官方文件:

> http://developer.android.com/guide/topics/ui/settings.html
> http://developer.android.com/reference/android/support/v7/preference/Preference.html

解决方法

解决方案1:使用AppCompatActivity的本机首选项整理

在AndroidStudio中,选择文件>新项目> …> SettingsActivity.此模板使用一种解决方法来改造本机PreferenceFragment以使用AppCompatActivity,类似于support.v4.Fragment或support.v7.PreferenceFragmentCompat.

> Pro:您现在可以在其中使用本机首选项功能
AppCompat应用使用AS模板时,这是一个快速的方法,您可以坚持现有的“首选项”文档和工作流.
Con:改装不是非常直观或干净.此外,由于通常建议使用可用的支持库,我不知道这种做法是如何面向未来的.

解决方案2:support.v7.preference.PreferenceFragmentCompat与AppCompatActivity

Pro:最大化兼容性
Con:有很大的差距来弥补.此外,这可能不适用于任何现有的preference-extensions-libs(例如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'
}

主题:
您需要在styles.xml中定义一个preferencesTheme,否则运行您的应用程序会引发异常.

<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light">
    <!-- Customize your theme here. -->
    <item name="preferenceTheme">@style/PreferenceThemeOverlay</item>
</style>

您可能希望将其分成7/14/21的不同风格.在撰写本文时,很多人抱怨这是错误的.有一个非常全面的答案here.

行为变化:使用本机首选项是非常简单的:所有您需要做的是定义/维护您的preferences.xml,并在PreferenceFragment中使用addPreferencesFromResource(R.xml.preferences).通过子类DialogPreference轻松完成自定义首选项,然后只是在preferences.xml … bam中引用.

不幸的是,support.v7.preference已经将与处理Fragment相关的所有内容都删除了,从而使其松散了很多内置的功能.而不是仅仅维护一个XML,现在你必须要分类并重写很多东西,所有这些都是不幸的.

PreferenceScreens:PreferenceScreens不再由框架管理.在您的preferences.xml(如docs中所述)中定义一个PreferenceScreen将显示该条目,但单击它不会执行任何操作.现在由您处理显示和导航子屏幕.无聊.

有一种方法(描述为here),将PreferenceFragmentCompat.OnPreferenceStartScreenCallback添加到您的PreferenceFragmentCompat.虽然这种方法快速实现,但它只是交换现有偏好片段的内容.缺点是:没有后退导航,你总是在顶部,这对用户来说不是很直观.

在另一种方法(描述here)中,您还必须管理后端堆栈,以实现预期的导航.这将使用preferencesScreen.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现在有任何处理实际对话框的东西,被删除.那位现在住在PreferenceDialogFragmentCompat.所以你必须要分两类,然后处理创建对话框并自己显示(说明here).

查看PreferenceFragmentCompat.onDisplayPreferenceDialog()的源代码显示它知道如何处理两个对话框首选项(EditTextPreference,ListPreference),其他所有你必须实现自己使用OnPreferenceDisplayDialogCallbacks …一个奇迹,为什么没有功能处理DialogPreference子类!

以下是一些实现大多数这些变通方法的代码,并将它们放在lib模块中:

https://github.com/mstummer/extended-preferences-compat.git

主要目的是:

>删除在每个应用程序/项目中扩展和调整活动和首选项分段的需要. preference.xml现在再次是唯一的每个项目文件进行更改/维护.
>按预期处理并显示偏好屏幕(子屏幕).
> Un-split DialogPreference可恢复原生行为.
>处理和显示DialogPreference的任何子类.

不要以为刚刚使用开箱即可,但在处理类似问题时可能会给您一些提示.给它一个旋转,让我知道,如果你有任何建议.

相关文章

ADB Remote ATV Android TV 的遥控器,基于 ADB Shell 命令 ...
使用Flutter自带的SearchDelegate组件实现搜索界面,通过魔改...
上篇文章讲解了怎么使用Kotlin的协程配合Retrofit发起网络请...
安卓开发——WebView+Recyclerview文章详情页,解决高度...
Android 如何解决dialog弹出时无法捕捉Activity的back事件 在...