14

I am using revision 26.0.1 of the Android Support Library to set custom fonts in my app. In my app's theme, I added:

<item name="android:fontFamily">@font/my_font</item>

It worked like a charm, converting the text in my whole app to my custom font. EXCEPT for my dialogs - specifically their titles, messages, and also their NumberPickers. In those places, fonts were not updated. (Radio buttons and checkboxes worked; so did the yes/no buttons)

Is there something I'm forgetting to add to my themes or styles? Or is this simply not supported yet by the support library?

A little more detail: I am using AppCompatDialogFragment to implement all my dialogs. In their onCreateDialog() methods, I create a dialog using AlertDialog.Builder then return it.

Thanks for the help!

yuval
  • 6,369
  • 3
  • 32
  • 44
  • 3
    I think it's a bug in the support library. On Android 26 it works if I specify both android:fontFamily and app:fontFamily for my main theme. Below 26 the dialog title font is not changed. I have tested with support library version 27.0.2. – devconsole Dec 04 '17 at 13:11
  • Add it as an issue in Google IssueTracker - https://issuetracker.google.com/ – HughHughTeotl Mar 30 '18 at 19:57
  • @devconsole Is this still a bug in 26.0.1 lib? – Krish May 02 '18 at 15:28
  • I think it is covered by this issue: https://issuetracker.google.com/issues/70479266 The status says it's "fixed" but I haven't tested it yet. – yuval Dec 08 '18 at 00:35

6 Answers6

5

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.

yuval
  • 6,369
  • 3
  • 32
  • 44
3

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)

danwilkie
  • 794
  • 6
  • 10
1

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);
lionscribe
  • 3,413
  • 1
  • 16
  • 21
  • Does it really work for you in terms of setting fontFamily for the alert's title? Because for me it doesn't. – Mikhail Jul 07 '18 at 11:05
  • @Mikhail Did you correctly define style for dialog? See https://stackoverflow.com/a/24560196/2661303 for example. – lionscribe Jul 08 '18 at 18:47
  • It seems not to be working with app compat alert dialogs. is your solution about the native one? – Mikhail Jul 09 '18 at 05:38
1

Perhaps not the case here, I had a similar issue and found that fontFamily would not be impimented using the AsyncLayoutInflater. This is also the case if the AlertDialog is nested inside the AsyncLayoutInflater. I had to convert to the conventional layout inflator in order for the custom font to show. For example,

This did not show fontFamily called from TextView XML.

AsyncLayoutInflater inflater =new AsyncLayoutInflater(activity);
    inflater.inflate(R.layout.dialog, null, new AsyncLayoutInflater.OnInflateFinishedListener() {
        @Override
        public void onInflateFinished(@NonNull View view, int resid, ViewGroup parent) {
            final TextView tv = view.findViewById(R.id.textview);
            tv.setText("Text with custom fontFamily called in XML, but won't work");
        }
});

This did show fontFamily called from TextView XML.

final ViewGroup nullParent = null;
final View view = activity.getLayoutInflater().inflate(R.layout.dialog, nullParent);
final TextView tv= view.findViewById(R.id.textview);
tv.setText("Text with custom fontFamily called in XML, and will work");
seekingStillness
  • 4,833
  • 5
  • 38
  • 68
-1

You can use custom Alert Dialog and set the font using Typeface. Have a look at below code snippet.

 AlertDialog dg = new AlertDialog.Builder(this).setMessage("Your Message").show();
 TextView tv = (TextView) dg.findViewById(android.R.id.message); // Your TextView of custom Alert Dialog
 Typeface fc=Typeface.createFromAsset(getAssets(),"fonts/FONT"); // This is your font file name.
 tv.setTypeface(fc); 
Akshay
  • 2,506
  • 4
  • 34
  • 55
Harshit Trivedi
  • 764
  • 9
  • 33
-1

you can inflate a custom layout in your dialog like this:

final android.support.v7.app.AlertDialog.Builder alertDialogBuilder = new android.support.v7.app.AlertDialog.Builder(context,
R.style.LimitAlertDialogStyle);
LayoutInflater layoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View alertLayout = layoutInflater.inflate(R.layout.date_layout, null);
TextView tv= (TextView) alertLayout.findViewById(R.id.tv);

Typeface fc=Typeface.createFromAsset(getAssets(),"fonts/FONT"); 
tv.setTypeface(fc); 
masoud vali
  • 1,528
  • 2
  • 18
  • 29