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.
If we go through the android sources we will find that Theme.AppCompat.Light.Dialog.Alert
theme inherits alertDialogStyle:
<item name="alertDialogStyle">@style/AlertDialog.AppCompat.Light</item>
Going through the AlertDialog.AppCompat.Light
style we will find that it uses default layout:
<item name="android:layout">@layout/abc_alert_dialog_material</item>
Further investigating sources, particularly layout @layout/abc_alert_dialog_material
, we will see that TextView
with id android:id="@android:id/message"
(this is message TextView
) uses style TextAppearance.AppCompat.Subhead
<TextView
android:id="@android:id/message"
style="@style/TextAppearance.AppCompat.Subhead"
... />
Overriding those style in app's values/styles.xml
file will change appearance of message in alert dialog:
<style name="TextAppearance.AppCompat.Subhead" parent="Base.TextAppearance.AppCompat.Subhead">
<item name="android:textSize">24sp</item>
<item name="android:textColor">#ff0000</item> <!-- we can change other parameters, e.g. textColor -->
</style>
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));
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