I'm trying to change font size of message in alert dialog through styles but I can't make it work. There is a lot of answers describing how to do this but almost all of them I found do it programmatically. I want to do this once in styles, not with every new alertdialog.
What I've done so far:
In \AndroidSDK\platforms\android-23\data\res\layout\alert_dialog.xml
I see the TextView that is showing the message:
<TextView android:id="@+id/message"
style="?android:attr/textAppearanceMedium"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="5dip" />
In \AndroidSDK\platforms\android-23\data\res\values\themes.xml
I see that the value of textAppearanceMedium
attribute is @style/TextAppearance.Medium
.
I've created a following style of which the parent is TextAppearance.AppCompat.Medium
. This style is then applied to android:textAppearanceMedium
attribute of AlertDialog's style as follows:
<style name="Theme.My" parent="Theme.AppCompat.Light.NoActionBar.FullScreen">
<item name="android:alertDialogTheme">@style/Theme.My.AlertDialog</item>
</style>
<style name="Theme.My.AlertDialog" parent="Theme.AppCompat.Light.Dialog.Alert">
<item name="android:textAppearanceMedium">@style/MyTextAppearanceMedium</item>
</style>
<style name="MyTextAppearanceMedium" parent="TextAppearance.AppCompat.Medium">
<item name="android:textSize">24sp</item>
</style>
...but the font size won't change. What's wrong?
I'm using AppCompat support lib, min SDK 16, target SDK 23.
Thank you.
AlertDialog was using the theme attribute ?android:attr/textAppearanceMedium"
for dialog content until Material Theme.
If you look at the source code of AlertDialog
it uses an AlertController
to manage the AlertDialog
. In AlertDialog
constructor we have this :
TypedArray a = context.obtainStyledAttributes(null,
com.android.internal.R.styleable.AlertDialog,
com.android.internal.R.attr.alertDialogStyle, 0);
mAlertDialogLayout = a.getResourceId(com.android.internal.R.styleable.AlertDialog_layout,
com.android.internal.R.layout.alert_dialog);
We can see that the layout for the AlertDialog
comes from an attribute called "layout" declared in declare-styleable name=AlertDialog
and defined at theme level in the attribute alertDialogStyle
.
Know, looking at alertDialogStyle
in Material theme we got this
<item name="alertDialogStyle">@style/AlertDialog.Material</item>
and at Alert.Dialog.Material we got <item name="layout">@layout/alert_dialog_material</item>
It's using alert_dialog_material and not alert_dialog.
In alert_dialog_material we have the same TextView
<TextView android:id="@+id/message"
style="@style/TextAppearance.Material.Subhead"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingStart="@dimen/alert_dialog_padding_material"
android:paddingTop="@dimen/alert_dialog_padding_top_material"
android:paddingEnd="@dimen/alert_dialog_padding_material" />
but the style points to a local theme instead of ?android:attr/textAppearanceMedium
and that's why you can't style the message like before.
SOLUTION 1:
We can only do this programmatically. Get the TextView
using the window from the Dialog and set the appearance you want:
android.support.v7.app.AlertDialog d = builder.show();
TextView tv = (TextView)d.getWindow().findViewById(android.R.id.message);
SOLUTION 2:
To make it more flexible we can define an attribute in attrs.xml
<resources>
<attr name="dialogMessageStyle" format="reference"/>
</resources>
Define the attribute in your theme:
<style name="MyStyle" ...>
<item name="dialogMessageStyle">@style/AlertDialogMessageAppearance</item>
</style>
And set it in code using:
TextView tv = (TextView)d.getWindow().findViewById(android.R.id.message);
TypedArray a = getTheme().obtainStyledAttributes(new int[]{R.attr.dialogMessageStyle});
tv.setTextAppearance(DialogActivity.this,a.getResourceId(0,0));