Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android: message font size in alertdialog through styles

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.

like image 661
Tomask Avatar asked Feb 03 '16 14:02

Tomask


2 Answers

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>
like image 128
Sergey Avatar answered Sep 21 '22 04:09

Sergey


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 AlertControllerto 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 AlertDialogcomes 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 TextViewusing 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));
like image 28
Sergio Serra Avatar answered Sep 20 '22 04:09

Sergio Serra