更新:我制作了一个库来解决这个问题(使用了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
参数。这意味着对话框的主题将受到您的活动主题在其 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
,而是调用了铃声选择器意图,因此它始终根据系统主题进行。查看这个答案:RingtonePreference Theme。所以我们可以将其标记为已解决。
问题2:AppCompat对话框缺少标题。到目前为止,我还没有找到解决方法。确实,我没有努力寻找。让我们把标题缺失视为一个小问题。
问题3:单选按钮可绘制对象未被改变,因此图形在被动和活动(有颜色)状态之间不一致 - 所有都是彩色的(不仅仅是你按下的那一个),或者全部都是灰色的。现在这真的很烦人。
问题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
的材料主题变体。
您可以使用提供的AlertDialog.Builder
(不要与其本地对应项混淆)来创建其实例。
AlertDialog
被硬编码到了ListPreference
中,因此我预计会出现一些问题。 - Eugen Pechanec