使用AppCompat-v7 22对话框皮肤在API < 21上会产生丑陋的阴影。

25

我正在使用AppCompat编写一个Material Design风格的应用程序。由于AppCompat不影响对话框,因此我正在对话框进行如下设置:

styles.xml:

<style name="AppTheme.Base" parent="Theme.AppCompat">
    <!-- Set AppCompat’s color theming attrs -->
    <item name="colorPrimary">@color/green</item>
    <item name="colorPrimaryDark">@color/green_darker</item>
    <item name="colorAccent">@color/accent</item>

    <item name="android:alertDialogTheme">@style/alertDialog</item>
    <item name="android:dialogTheme">@style/alertDialog</item>
</style>

<style name="alertDialog" parent="Theme.AppCompat.Dialog">
    <item name="colorPrimary">@color/green</item>
    <item name="colorPrimaryDark">@color/green_darker</item>
    <item name="colorAccent">@color/accent</item>
</style>

在 Android API >= 21 上,我得到了我想要的结果,但在其他设备上,对话框周围会出现一个“框”。

有没有一种方法可以消除对话框周围的“框”,并且即使在 API < 21 上也可以应用颜色和 Material 主题,最好不需要任何其他依赖项?

API < 21 上的应用:

App on API < 21

API >= 21 上的应用:

App on API >= 21


此外,这也会在非棒棒糖API上超出边界。[图片](http://i.imgur.com/y0FEsVz.png) - snowdragon
同意,minSdk=11 真的很难处理。假设我选择 minSdk=14,我该如何解决过度绘制的问题?将 Theme.AppCompat.Dialog 替换为 android:Theme.DeviceDefault.Dialog.Alert 会导致崩溃。 - snowdragon
你能否在原问题中更新堆栈跟踪信息?我曾经遇到过一些崩溃问题,当时我在这些对话框中使用了TextAppearance.AppCompat.*。根据异常情况,你可能需要定义自定义文本外观。 - Eugen Pechanec
1
是的,就像我之前所说的那样。在这些对话框中使用的文本外观不能继承或使用 TextAppearance.AppCompat.*。定义自定义文本外观样式并使用它们。继承 @android:TextAppearance 并根据 Material Design 规范(文本类型 Body 1)自定义 textColortextSize,你就可以了。 - Eugen Pechanec
已报告:https://code.google.com/p/android/issues/detail?id=194475 - Mygod
显示剩余6条评论
5个回答

33

使用新的AppCompat v22.1,您可以使用新的android.support.v7.app.AlertDialog或新的AppCompatDialog

只需像这样使用代码(当然,在您的情况下,您需要使用自定义布局来拥有进度条):

import android.support.v7.app.AlertDialog

AlertDialog.Builder builder =
       new AlertDialog.Builder(this, R.style.AppCompatAlertDialogStyle);
            builder.setTitle("Dialog");
            builder.setMessage("Lorem ipsum dolor ....");
            builder.setPositiveButton("OK", null);
            builder.setNegativeButton("Cancel", null);
            builder.show();

并使用类似这样的样式:

<style name="AppCompatAlertDialogStyle" parent="Theme.AppCompat.Light.Dialog.Alert">
        <item name="colorAccent">#FFCC00</item>
        <item name="android:textColorPrimary">#FFFFFF</item>
        <item name="android:background">#5fa3d0</item>
    </style>

你知道我们如何仅更改正按钮的文本颜色和背景颜色吗? - Neige
@Neige 在 builder.show(); 后面以相同的方式使用 .setBackgroundColor() 或者 .builder.getButton(DialogInterface.BUTTON_POSITIVE).setTextColor(Color.parseColor("#FF0000")); - Sdghasemi
8
对于ProgressDialog呢? - Guilherme Torres Castro

10

如果有人还在寻找简单有效的解决方案,只需在“alertDialog”样式中添加此行:

<item name="android:windowBackground">@android:color/transparent</item>

顺便提一句,更改此属性还会影响API >= 21上的PreferenceFragment对话框,因此请确保您使用不同的样式:在API < 21上使用透明背景,而在API >= 21上不做任何更改。


这是正确的答案。创建一个扩展应用兼容主题并覆盖窗口背景,如上所述。在ProgressDialog的构建中应用该主题,就不会再出现奇怪的背景了。 - Matt Kranzler

6
我使用android.support.v7.app.AlertDialog创建所有的AlertDialog时,也遇到了新的AppCompat 22库的相同问题,但额外的背景层只影响了ProgressDialogs。
使用我的自定义主题样式为所有的AlertDialog设置样式时,所有的AlertDialog都看起来很棒,但是ProgressDialogs的背景却有像OP所描述的奇怪覆盖层。
我可以选择每次构建ProgressBar时设置特定的样式,但我正在寻找一种应用范围内的解决方案。
在这两个链接的帮助下:如何像专业人士一样设计AlertDialogsJoerg Richter Blog,我能够摆脱<21 ProgressDialogs上绘制的额外图层。
我发现的问题是,在所有版本中,ProgressBar根据“android:alertDialogStyle”中默认定义的内容绘制其背景。
因此,为了去除额外的层,我不得不定义自己的样式并将它们设置为“android:alertDialogStyle”。这样做,我还覆盖了应用于ProgressDialogs的默认布局。
这是我的themes.xml:
<item name="android:alertDialogTheme">@style/MyAlertDialogTheme</item>
<item name="alertDialogTheme">@style/MyAlertDialogTheme</item>
<item name="android:alertDialogStyle">@style/MyAlertDialogStyles</item>

和我的 styles.xml 文件:

<style name="MyAlertDialogTheme">
    <item name="android:windowIsFloating">true</item>
    <item name="android:windowBackground">@android:color/transparent</item>
    <item name="android:windowContentOverlay">@null</item>
    <item name="android:windowAnimationStyle">@android:style/Animation.Dialog</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="android:background">@color/theme_alert_dialog_background</item>
    <item name="colorAccent">@color/theme_accent_1</item>
</style>

<style name="AlertDialog">
    <item name="android:fullDark">@android:color/transparent</item>
    <item name="android:topDark">@android:color/transparent</item>
    <item name="android:centerDark">@android:color/transparent</item>
    <item name="android:bottomDark">@android:color/transparent</item>
    <item name="android:fullBright">@android:color/transparent</item>
    <item name="android:topBright">@android:color/transparent</item>
    <item name="android:centerBright">@android:color/transparent</item>
    <item name="android:bottomBright">@android:color/transparent</item>
    <item name="android:bottomMedium">@android:color/transparent</item>
    <item name="android:centerMedium">@android:color/transparent</item>
</style>

这对我有用。我不得不创建两个文件夹(值,值-21)。我在文件夹values\styles.xml中实现了解决方案。最后我摆脱了奇怪的边框。完美。 - CreateAHero
优秀的解决方案。为了澄清,请使用名为“AlertDialog”的样式作为android:alertDialogStyle,并将其放在您的默认style.xml中。实际上,我不需要在我的v21 style.xml中创建另一个样式。 - idunnololz

6

ProgressDialog - 适用于Android 5以下版本

dialog.getWindow().setBackgroundDrawableResource(android.R.color.transparent);

或者
dialog.getWindow().clearFlags(LayoutParams.FLAG_DIM_BEHIND);

2

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接