我正在努力改变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
的背景和按钮样式是应用的,但不是屏幕截图中显示的文本颜色:
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版本中使用过这个解决方案,无法记住问题所在,但无论如何,并没有解决目前的问题:(
有谁可以告诉我发生了什么?
答案 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(...);
...
}