I am struggling with changing the TEXT color of AppCompat DialogFragments.
My App uses a DARK theme (Theme.AppCompat.NoActionBar
), but for dialogs I want a LIGHT theme. I am using Build Tools, Support Library and compileSdkVersion to 25, shall it matters.
I am able to change everything else on the dialog (title, background, window background) but not the primary and accented text colors, that keep on using the (white) settings for the dark theme, resulting in white text over white background.
I've tried dozens of solutions in similar questions here in SO, like:
1) The easy one: On the 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>
With this solution, the background and buttons style from AppCompat.Light.Dialog.Alert
IS APPLIED, but not the text colors as you can see in the screenshot:
2) Manually specifying the style on the AlertDialog Creation:
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity(), R.style.AppCompatAlertDialogStyle);
LayoutInflater inflater = getActivity().getLayoutInflater();
View hostView = mHostView = inflater.inflate(layoutId, null);
Same problem. Light background, Light text.
3) Using a ContextWrapper:
ContextThemeWrapper ctw = new ContextThemeWrapper(getActivity(), R.style.AppCompatAlertDialogStyle);
AlertDialog.Builder builder = new AlertDialog.Builder(ctw);
Nothing :( Same thing happens
4) Manually specifying other exotic constants I came across the many posts here in SO, like
Theme_DeviceDefault_Light_Dialog_Alert
THEME_DEVICE_DEFAULT_LIGHT
This was just a desperate attempt, but anyways the text is not changed
5) Specifying the style in the fragment rather than on the dialog
Dialog_Meta newFragment = new Dialog_Meta();
newFragment.setStyle(DialogFragment.STYLE_NORMAL, R.style.AppCompatAlertDialogStyle);
newFragment.show(fragmentManager, TAG);
I used this solution time ago in a very old API version, can't remember what was the problem, but anyways, doesn't solve the present issue :(
Can anybody tell me what's going on?
The problem here is the custom View
you're setting on the AlertDialog
. Though you've set a certain theme for AlertDialog
s in general, that View
is being inflated with the Activity
's theme, which doesn't have those overridden color attribute values.
There are several ways to solve this.
• Create a ContextThemeWrapper
around the Activity
's Context
with the custom R.style
, and obtain the LayoutInflater.from()
that.
ContextThemeWrapper ctw = new ContextThemeWrapper(getActivity(), R.style.AppCompatAlertDialogStyle);
LayoutInflater inflater = LayoutInflater.from(getActivity());
View hostView = mHostView = inflater.inflate(layoutId, null);
...
• As discovered by the OP, rupps, the AlertDialog.Builder
will already have the alertDialogTheme
wrapped on the Context
it's given, and its getContext()
method will return the appropriate ContextThemeWrapper
, which can be used for the Inflater.
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
LayoutInflater inflater = LayoutInflater.from(builder.getContext()); // THIS IS THE KEY
View hostView = mHostView = inflater.inflate(layoutId, null);
...
From Google's Documentation of AlertDialog.Builder
's getContext()
method:
/**
* 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() {
...
• The theme can be set as the android:theme
attribute on the root View
of the Dialog
's layout.
<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">
...
• Rather than handling the inflation yourself, the layout's ID can be passed in the Builder
's setView()
call, and it will be inflated with the alertDialogTheme
.
With this method, however, the View
objects from the layout won't be available until the Dialog
is shown. In a DialogFragment
, this will be in the onStart()
method.
@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(...);
...
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With