java - 将 AppCompat 主题应用于 PreferenceFragment 中的个人首选项

标签 java android android-theme

我一直在努力让我的 PreferenceFragment 与我的应用程序的其余部分具有相同的基于 Material 的主题和样式(通过 AppCompat)。我用来管理所有应用程序设置的 PreferenceFragment 如下所示:

enter image description here

从上面的截图可以看出,我可以使用 colorAccentcolorPrimary 和其他一些方法自定义 PreferenceFragment属性。我的 PreferenceFragment 主题如下:

<style
    name="settingsTheme"
    parent="Theme.AppCompat.Light.DarkActionBar">
    <item name="colorPrimary">@color/blue_grey_500</item>
    <item name="colorAccent">@color/blue_grey_500</item>
    <item name="android:textColor">@color/black_text_alt</item>
    <item name="android:textColorSecondary">@color/black_secondary_text</item>
</style>

但是,尽管我尽了最大的努力,我还是无法将主题应用于我的 PreferenceFragment 中的各个元素,例如 ListPreferenceEditTextPreference ;所有首选项仍保留标准 AppCompat 主题:

enter image description here

我发现一篇 2 年前的帖子讨论了这个问题,尽管没有真正的解决方案:How to apply theme to <PreferenceScreen> elements of a <PreferenceCategory>

我想知道自 AppComat V21 发布以来是否有人能够成功地将主题应用于首选项。如果没有,是否有任何可行的解决方法可用于将自定义主题应用于个人偏好?

最佳答案

更新:我创建了一个库来解决这个问题(使用 AppCompat r22):https://github.com/consp1racy/android-support-preference


ListPreference 扩展了 DialogPreference,它使用这段代码来创建对话框:

mBuilder = new AlertDialog.Builder(context)
    .setTitle(mDialogTitle)
    .setIcon(mDialogIcon)
    .setPositiveButton(mPositiveButtonText, this)
    .setNegativeButton(mNegativeButtonText, this);

如您所见,AlertDialog.Builder 构造函数没有提供第二个可选的 int theme 参数。这意味着对话框将以您的 Activity 主题在其 android:alertDialogTheme 属性中的任何内容为主题。

现在您必须为您的对话框创建一个自定义主题,该主题源自 Theme.AppCompat.Dialog,如下所示:

<style name="Theme.YourApp.Dialog.Alert" parent="Theme.AppCompat.Light.Dialog">
  <item name="android:windowBackground">@android:color/transparent</item>
  <item name="android:windowContentOverlay">@null</item>
  <item name="android:windowMinWidthMajor">@android:dimen/dialog_min_width_major</item>
  <item name="android:windowMinWidthMinor">@android:dimen/dialog_min_width_minor</item>
  <item name="colorAccent">@color/accent_yourapp</item>
  <item name="colorPrimary">@color/primary_yourapp</item>
  <item name="colorPrimaryDark">@color/primary_dark_yourapp</item>
</style>

问题1:上述解决方案不适用于RingtonePreference,因为它没有扩展ListPreference,而是调用了铃声选择器intent,所以它是始终根据系统主题。看看这个答案: RingtonePreference Theme所以我们可以将其标记为已解决。

问题 2: AppCompat 对话框缺少标题。到目前为止,我还没有找到解决此问题的方法。确实,我看的不够努力。让我们忽略标题缺失作为一个小问题。

问题 3: 单选按钮 drawable 没有发生变化,因此图形在被动和主动(彩色)状态之间不一致 - 全部都是彩色的(不仅仅是你正在按下的那个)或者全部都是彩色的灰色的。现在这真的很烦人

问题 2 和 3 迫使我采取另一条路线 - 我的对话框主题在 API 14+ 上看起来像这样

<style name="Theme.MyApp.Dialog.Alert" parent="android:Theme.DeviceDefault.Light.Dialog.MinWidth">
  <item name="android:windowBackground">@android:color/transparent</item>
  <item name="android:windowContentOverlay">@null</item>
</style>

在 API 21+ 上像这样

<style name="Theme.YourApp.Dialog.Alert" parent="android:Theme.DeviceDefault.Light.Dialog.MinWidth">
  <item name="android:colorPrimary">@color/primary_yourapp</item>
  <item name="android:colorPrimaryDark">@color/primary_dark_yourapp</item>
  <item name="android:colorAccent">@color/accent_yourapp</item>
</style>

这些值是通过爬取平台的源文件实验获得的,并经过充分测试。

关键是唯一可靠的解决方案似乎是使用设备默认对话框主题。 Lollipop 之前的唯一选择是浅色或深色。在 Lollipop 上,这将按预期和要求工作。

编辑: 因为 appcompat-v7-r21.1.0 你可以使用 AppCompatDialog这是原生 AlertDialog 的 Material 主题变体。

您可以使用提供的 AlertDialog.Builder (不要与它的本地对应物混淆)用于创建它的实例。

关于java - 将 AppCompat 主题应用于 PreferenceFragment 中的个人首选项,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28241380/

相关文章:

java - HiveServer2 JDBC 客户端 : Unable to connect to MetaStore

java - 具有多个空值的多图上的 Guava 空指针

android - ImageView 上的 TranslateAnimation (Android)

android - AlertDialog 中的样式单选按钮和文本

java - BufferedImage 数组的 NullPointerException

java - 将 bean 注入(inject)到使用 mockito 创建的模拟中

android - 如何使用 Firebase Functions 将 FCM 发送给用户?

android - 在 Android OpenCV 中设置关键点数

android - View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN 不工作

java - 如何使用 Material Design 更改操作栏文本颜色?