如何使用支持库26在AlertDialog中设置自定义字体

时间:2017-08-17 03:47:54

标签: android fonts android-support-library android-fonts android-8.0-oreo

我正在使用Android Support Library的修订版26.0.1在我的应用中设置自定义字体。在我的应用主题中,我添加了:

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

它就像一个魅力,将我整个应用程序中的文本转换为我的自定义字体。除了我的对话框 - 特别是他们的标题,消息以及他们的NumberPickers。在那些地方,字体没有更新。 (单选按钮和复选框工作;是/否按钮也是如此)

有什么我忘了添加到我的主题或风格?或者支持库是否支持这个?

更多细节:我正在使用AppCompatDialogFragment来实现我的所有对话框。在他们的onCreateDialog()方法中,我使用AlertDialog.Builder创建了一个对话框,然后将其返回。

感谢您的帮助!

6 个答案:

答案 0 :(得分:5)

谢谢大家回答,但遗憾的是这些解决方案都不适合我。我希望他们能为别人工作。

我已经得出结论,这是支持库中的一个错误,希望谷歌能够修复。与此同时,我开发了这个hacky解决方法:

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);
    }
}

这可以通过支持库为其提供的ID扫描对话框的视图树中的标题和消息视图。如果支持库要更改这些ID,这将不再有效(这就是为什么它是hacky)。希望谷歌解决这个问题,我不再需要这样做了。

答案 1 :(得分:2)

我发现每次创建AlertDialog时都只需要对Java代码进行一行更改。

第1步

创建包含具有正确字体集的TextView的自定义可重用布局。称之为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" />

第2步

在某处创建一个可重复使用的辅助函数,该函数将使此布局膨胀并将文本设置为所需的字符串

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;
}

第3步

在代码中的每个AlertDialog.Builder链中,替换以下行:

.setMessage(messageString)

这一行:

.setView(createMessageView(messageString, context))

(请注意,相同的方法适用于标题TextView。您可以通过在构建器中调用setCustomTitle()来为标题应用自定义视图)

答案 2 :(得分:1)

创建对话框构建器时应使用ContextThemeWrapper。喜欢这个

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

如果您仅支持SDK 11及更高版本,则可能需要使用

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

答案 3 :(得分:0)

在这里可能不是这样,我遇到了类似的问题,发现使用fontFamily不会使AsyncLayoutInflater受害。如果AlertDialog嵌套在AsyncLayoutInflater中,情况也是如此。为了显示自定义字体,我不得不转换为传统的布局充气机。例如,

这没有显示从fontFamily XML调用的TextView

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");
        }
});

这确实显示了fontFamily是从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");

答案 4 :(得分:-1)

您可以使用自定义Alert Dialog并使用Typeface设置字体。看看下面的代码片段。

 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); 

答案 5 :(得分:-1)

您可以在对话框中为自定义布局充气,如下所示:

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);