Android 如何将support.v7.preference与AppCompat一起使用以及潜在的缺点

Android 如何将support.v7.preference与AppCompat一起使用以及潜在的缺点,android,android-appcompat,android-preferences,preferencescreen,preference-v7,Android,Android Appcompat,Android Preferences,Preferencescreen,Preference V7,我试图使用support.v7.preference为AppCompat应用程序实现首选项。由于support.v7.preference与本机的首选项有一些显著的差异,所以我花了几天的时间来整理它。。。一旦你知道了这一点就不算太糟糕了,但不幸的是,那里几乎没有文档。我想我应该分享我的发现,这样其他人就不必经历同样的痛苦 所以问题: 如何最好地实现AppCompat应用程序的首选项(PreferenceFragment和AppCompativity不兼容) 以下是几个相关问题: 官

我试图使用support.v7.preference为AppCompat应用程序实现首选项。由于support.v7.preference与本机的首选项有一些显著的差异,所以我花了几天的时间来整理它。。。一旦你知道了这一点就不算太糟糕了,但不幸的是,那里几乎没有文档。我想我应该分享我的发现,这样其他人就不必经历同样的痛苦


所以问题: 如何最好地实现AppCompat应用程序的首选项(PreferenceFragment和AppCompativity不兼容)

以下是几个相关问题:
官方文件如下:
解决方案1:Native
PreferenceFragment
with
AppCompatActivity
在AndroidStudio中,选择文件>新建项目>设置活动。此模板使用一种变通方法,对本机
PreferenceFragment
进行改进,以与
AppCompatActivity
配合使用,类似于
support.v4.Fragment
support.v7.PreferenceFragmentCompat

  • Pro:您现在可以在一个应用程序中使用本机首选项功能
    AppCompat
    app。使用AS模板时,这是一种快速的方法,您可以坚持使用现有的首选项文档和工作流
  • 缺点:改装不是很直观,也不干净。此外,由于通常建议在可用的情况下使用support LIB,因此我不确定这种方法是否具有未来的可行性

解决方案2:
support.v7.preference.PreferenceFragmentCompat
with
AppCompatActivity
  • 优点:最大化兼容性
  • 缺点:要弥合很多差距。此外,这可能不适用于任何现有的首选项扩展库(例如,
    colorpocker
    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中定义
首选主题
,否则运行应用程序将引发异常

<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light">
    <!-- Customize your theme here. -->
    <item name="preferenceTheme">@style/PreferenceThemeOverlay</item>
</style>
自定义对话框首选项:创建自己的首选项也从琐碎变成了枯燥
DialogPreference
现在已删除任何与实际对话框相关的内容。该位现在位于
首选项对话框FragmentCompat
中。因此,您必须将这两个类都分为子类,然后创建对话框并自己显示它(已解释)

查看
首选项FragmentCompat.onDisplayPreferenceDialog()
的源代码可以看出,它知道如何准确地处理两个对话框首选项(
EditTextPreference
ListPreference
),其他一切都必须使用
OnPreferenceDisplayDialogCallback
实现。。。有人想知道,为什么没有处理
对话框首选项的子类的功能


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

主要意图是:

  • 不再需要在每个应用程序/项目中扩展和摆弄
    活动
    首选片段
    preference.xml
    现在又是唯一要更改/维护的每个项目文件
  • 按预期处理和显示首选屏幕(子屏幕)
  • 取消拆分
    对话框首选项
    以恢复本机行为
  • 处理和显示对话框首选项的任何子类

不要认为它足够干净,可以开箱即用,但在处理类似问题时,它可能会给你一些提示。试一试,如果你有任何建议,请告诉我。

我有另一种解决方案,我希望得到反馈

我为我的preferencefragment做了一个自定义布局,在左上角有一个“后退”按钮

首先,在“onCreatePreference”中,我存储了根首选项屏幕:

root = this.getPreferenceScreen();
然后,我添加了如上所述的OnPreferenceStartScreenCallback,并在其他线程中添加,以使片段转到子屏幕,但在我的“onPreferenceStartScreen”中,我还将后退按钮设置为可见,如下所示:

    public boolean onPreferenceStartScreen(PreferenceFragmentCompat preferenceFragmentCompat, PreferenceScreen preferenceScreen) {
        preferenceFragmentCompat.setPreferenceScreen(preferenceScreen);
        backButton.setVisibility(View.VISIBLE);
        return true;
}
最后,backButton clickhandler:

    setPreferenceScreen(root);
    back.setVisibility(View.GONE);
这似乎对我很管用。很明显,后堆栈不起作用,但我可以接受,因为有一个后退按钮

不完美,但考虑到糟糕的API,我觉得我很高兴


我很想知道是否有人认为这种方法有任何问题。

你是一个救生员Max@maxdownunder!!但这是否适用于子屏幕?似乎没有任何效果,明白了。我在“prefreefragmentcompat::onCreatePreferences(..)中有“addPreferencesFromResource(R.xml.settings)”而不是“setPreferencesFromResource(R.xml.settings,rootKey)”“我没有任何线索
编译'com.android.support:support-v4:23.1.1'
甚至是一个选项,谢谢你指出这一点,省去了我的头疼!因此,谷歌实际上已经否决了整个功能。谁有时间来搞这些?滚动您自己的UI并保存到共享首选项可能会快得多。
    setPreferenceScreen(root);
    back.setVisibility(View.GONE);