How do I set a custom font in an AlertDialog using Support Library 26

I've found a way that only requires a one-line change to Java code every time you create an AlertDialog.

Step 1

Create a custom, reusable layout containing a TextView with the correct font set. Call it alert_dialog.xml:

<?xml version="1.0" encoding="utf-8"?>
<TextView
    xmlns:android="http://schemas.android.com/apk/res/android"
    style="@style/SomeStyleWithDesiredFont"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:padding="@dimen/spacing_2x" />

Step 2

Create a reusable helper function somewhere that will inflate this layout and set the text to your desired string

public static TextView createMessageView(String message, Context context) {
    TextView messageView = (TextView) LayoutInflater.from(context).inflate(R.layout.alert_dialog, null, false);
    messageView.setText(message);
    return messageView;
}

Step 3

In every AlertDialog.Builder chain in your code, replace this line:

.setMessage(messageString)

with this line:

.setView(createMessageView(messageString, context))

(Note that the same approach should work for the title TextView. You can apply a custom view for the title by calling setCustomTitle() in your builder)


You should use a ContextThemeWrapper when creating the dialog builder. Like this

ContextThemeWrapper wrappedContext = new ContextThemeWrapper(context, R.style.mystyle); 
AlertDialog.Builder builder = new AlertDialog.Builder(wrappedContext);

If you are supporting only SDK 11 and above, you may want to use

ContextThemeWrapper wrappedContext = new ContextThemeWrapper(context, R.style.mystyle); 
AlertDialog.Builder builder = new AlertDialog.Builder(wrappedContext, R.style.mystyle);

Thank you everybody who answered, but unfortunately none of those solutions worked for me. I hope they will work for someone else.

I've concluded that this is a bug in the support library, and hopefully Google will fix. In the meantime, I developed this hacky workaround:

public static void applyCustomFontToDialog(Context context, Dialog dialog) {
    Typeface font = ResourcesCompat.getFont(context, R.font.my_font);
    if (font != null) {
        TextView titleView = dialog.findViewById(android.support.v7.appcompat.R.id.alertTitle);
        TextView messageView = dialog.findViewById(android.R.id.message);
        if (titleView != null) titleView.setTypeface(font, Typeface.BOLD);
        if (messageView != null) messageView.setTypeface(font);
    }
}

This works by scanning the dialog's view tree for the title and message views by the IDs that the support library gives them. If the support library were to change these IDs, this would no longer work (which is why it's hacky). Hopefully Google fixes this issue and I won't need to do this anymore.