AppCompatDialog:无法更改文字颜色

时间:2016-10-29 22:39:11

标签: android material-design android-appcompat android-theme

我正在努力改变AppCompat DialogFragments的TEXT颜色。

我的应用使用了DARK主题(Theme.AppCompat.NoActionBar),但对于对话框,我想要一个LIGHT主题。我正在使用Build Tools,Support Library和compileSdkVersion到25,这很重要。

我可以更改对话框中的所有其他内容(标题,背景,窗口背景)但不能更改主要和带重音的文本颜色,继续使用黑色主题的(白色)设置,导致白色背景上的白色文字。

我在SO中尝试过类似问题的数十种解决方案,例如:

1)简单的一个:在styles.xml上:

 <!-- Application theme. -->
<style name="AppTheme" parent="AppBaseTheme">
    <item name="alertDialogTheme">@style/AppCompatAlertDialogStyle</item>
    <item name="android:alertDialogTheme">@style/AppCompatAlertDialogStyle</item>
</style>

<style name="AppCompatAlertDialogStyle" parent="Theme.AppCompat.Light.Dialog.Alert">
    <!-- ignored !!!! -->
    <item name="colorPrimary">#ff0000</item>
    <!-- ignored !!!! -->
    <item name="colorPrimaryDark">#ff0000</item>
    <!-- ignored !!!! -->
    <item name="colorAccent">#ff0000</item>
    <!-- ignored !!!! -->
    <item name="android:textColorPrimary">#F040FF</item>
    <!-- ignored !!!! -->
    <item name="android:textColor">#F040FF</item>

</style>

使用此解决方案,来自AppCompat.Light.Dialog.Alert的背景和按钮样式是应用的,但不是屏幕截图中显示的文本颜色:

enter image description here

2)在AlertDialog Creation上手动指定样式:

    AlertDialog.Builder builder = new AlertDialog.Builder(getActivity(), R.style.AppCompatAlertDialogStyle);
    LayoutInflater inflater = getActivity().getLayoutInflater();
    View hostView = mHostView = inflater.inflate(layoutId, null);

同样的问题。浅色背景,浅色文字。

3)使用ContextWrapper:

    ContextThemeWrapper ctw = new ContextThemeWrapper(getActivity(),  R.style.AppCompatAlertDialogStyle);
    AlertDialog.Builder builder = new AlertDialog.Builder(ctw);

没什么:(同样的事情发生了

4)手动指定其他奇特的常量我在SO中遇到过很多帖子,例如

Theme_DeviceDefault_Light_Dialog_Alert
THEME_DEVICE_DEFAULT_LIGHT

这只是一次绝望的尝试,但无论如何文本都没有改变

5)在片段中而不是在对话框中指定样式

    Dialog_Meta newFragment = new Dialog_Meta();
    newFragment.setStyle(DialogFragment.STYLE_NORMAL, R.style.AppCompatAlertDialogStyle);
    newFragment.show(fragmentManager, TAG);

我之前在一个非常旧的API版本中使用过这个解决方案,无法记住问题所在,但无论如何,并没有解决目前的问题:(

有谁可以告诉我发生了什么?

1 个答案:

答案 0 :(得分:2)

此处的问题是您在View上设置的自定义AlertDialog。虽然您通常为AlertDialog设置了某个主题,但View的主题却被Activity的主题夸大了,而这些主题没有被覆盖的颜色属性值。< / p>

有几种方法可以解决这个问题。

•使用自定义ContextThemeWrapper围绕Activity Context创建R.style,并获取LayoutInflater.from()。{/ p>

ContextThemeWrapper ctw = new ContextThemeWrapper(getActivity(), R.style.AppCompatAlertDialogStyle);
LayoutInflater inflater = LayoutInflater.from(getActivity());
View hostView = mHostView = inflater.inflate(layoutId, null);
...

•正如OP rupps所发现的那样,AlertDialog.Builder已经将alertDialogTheme包裹在Context给出的getContext()及其ContextThemeWrapper方法上将返回适当的AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); LayoutInflater inflater = LayoutInflater.from(builder.getContext()); // THIS IS THE KEY View hostView = mHostView = inflater.inflate(layoutId, null); ... ,可用于Inflater。

AlertDialog.Builder

来自Google的getContext() /** * Returns a {@link Context} with the appropriate theme for dialogs created by this * Builder. * Applications should use this Context for obtaining LayoutInflaters for inflating views * that will be used in the resulting dialogs, as it will cause views to be inflated with * the correct theme. * * @return A Context for built Dialogs. */ public Context getContext() { ... 方法文档:

android:theme

•主题可以设置为View布局的根Dialog上的<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:theme="@style/AppCompatAlertDialogStyle"> ... 属性。

Builder

•不是自己处理通货膨胀,而是可以在setView()的{​​{1}}来电中传递布局的ID,并使用alertDialogTheme进行通货膨胀。

但是,使用此方法,在显示View之前,布局中的Dialog对象将不可用。在DialogFragment中,这将采用onStart()方法。

@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
    AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
    builder.setView(R.layout.dialog);
    return builder.create();
}

@Override
public void onStart() {
    super.onStart();

    final Dialog dialog = getDialog();
    dialog.findViewById(R.id.dialog_button).setOnClickListener(...);
    ...
}