【问题标题】:How to set custom font for alert dialog in android?如何在android中为警报对话框设置自定义字体?
【发布时间】:2012-10-14 15:43:03
【问题描述】:

在我的 android 应用程序中,单击按钮后会出现一个警告对话框。我想为警报设置 自定义字体。我在网上搜索并找到了一些关于这个主题的教程和问题,但它们都不适合我。

如何更改字体?

谢谢

【问题讨论】:

    标签: android android-layout


    【解决方案1】:

    为此,您可以使用警报构建器来构建警报。然后,您从此警报中获取 TextView,然后设置警报的字体。

    AlertDialog dialog = new AlertDialog.Builder(this).setMessage("Hello world").show();
    TextView textView = (TextView) dialog.findViewById(android.R.id.message);
    Typeface face=Typeface.createFromAsset(getAssets(),"fonts/FONT"); 
    textView.setTypeface(face); 
    

    【讨论】:

    • 那很好,记得在获得权限后批准和投票,以便其他人也能获得此帮助。
    • 我正在尝试做,但你的代码真的很棒 :) 非常感谢
    • 不幸的是,这会在 API 20 上引发空指针异常,无法找到 textView。
    • @mikeswright49 如何为这种方式添加确定和取消按钮?
    • 如果你也想更改标题的字体,我可以使用android.support.v7.appcompat.R.id.alertTitle
    【解决方案2】:

    您可以定义自己想要显示的对话框的布局。

    这是一个链接

    Creating a custom dialog in Android

    在您的布局中,您可以使用所需的 typeFace 定义 TextViews。您需要下载所需字体的 otf 文件。将它们放在您的资产目录中。并将其设置为 TextView 的 TypeFace。以及如何设置字体

    这很有帮助

    How to change the font on the TextView?

    【讨论】:

    • 我在 mikeswright49 的上一篇文章中得到了答案。但感谢您的关注。
    【解决方案3】:

    以上答案对我不起作用。

    我使用了以下方法

    // Initializing the alertDialog
    AlertDialog alertDialog = new AlertDialog.Builder(QuizActivity.this).create();
    alertDialog.setTitle("Warning");
    alertDialog.setMessage("Are you sure you want to exit?");
    alertDialog.show(); // This should be called before looking up for elements
    
    
    // Getting the view elements
    TextView textView = (TextView) alertDialog.getWindow().findViewById(android.R.id.message);
    TextView alertTitle = (TextView) alertDialog.getWindow().findViewById(R.id.alertTitle);
    Button button1 = (Button) alertDialog.getWindow().findViewById(android.R.id.button1);
    Button button2 = (Button) alertDialog.getWindow().findViewById(android.R.id.button2);
    
    // Setting font
    textView.setTypeface(FontHelper.getFont(Fonts.MULI_REGULAR));
    alertTitle.setTypeface(FontHelper.getFont(Fonts.MULI_REGULAR));
    button1.setTypeface(FontHelper.getFont(Fonts.MULI_BOLD));
    button2.setTypeface(FontHelper.getFont(Fonts.MULI_BOLD));
    

    在 7.1.1 上测试

    注意:确保在显示 dialog 后获得该元素。没有这个你会得到NullPointerException

    【讨论】:

    • @ManojPerumarath 您可以使用 android.R.id.title
    • @Cerlin,按钮 1 和按钮 2 是使用构建器创建的正按钮和负按钮,还是布局中膨胀的按钮?
    【解决方案4】:

    自定义警报对话框标题文本视图

                 TextView tv_message = new TextView(this);
    
                Typeface typeface = Typeface.createFromAsset(
                        getAssets(),
                        "fonts/OpenSans-Semibold.ttf"
                );
    
    
                // Set the text view layout parameters
                tv_message.setLayoutParams(
                        new 
          ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 
          ViewGroup.LayoutParams.WRAP_CONTENT)
                );
    
                // Set message text color
                tv_message.setTextColor(Color.RED);
    
                // Set message gravity/text align
                tv_message.setGravity(Gravity.START);
    
                // Set message text size
                tv_message.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 16);
    
                // Set message custom font
                tv_message.setTypeface(typeface);
    
                // Set message background color
                tv_message.setBackgroundColor(Color.YELLOW);
    
                // Set message text padding
                tv_message.setPadding(15, 25, 15, 15);
    
                tv_message.setText("Are you sure?");
                tv_message.setTextColor(Color.BLACK);
    

    【讨论】:

    • 谢谢它的工作,下面是我的代码TextView tv_title = new TextView(this); tv_title.setText(Title); tv_title.setTextColor(getResources().getColor(R.color.white)); Typeface typeface = ResourcesCompat.getFont(context, R.font.work_sans_regular); tv_title.setTypeface(typeface); pDialog.setCustomTitle(tv_title); 用它来设置 ProgressDialog 字体
    【解决方案5】:

    我知道这是一个老问题,但我将这里留给仍在寻找解决方案的人。

    如果您只想更改文本格式,您只需覆盖alertDialogTheme 属性即可更改AlertDialog 的主题。

    示例,使用应用程序主题

    <style name="MyTheme" parent="Theme.AppCompat.Light.NoActionBar">
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccent</item>
    
        <!-- This will override the Alert Dialog theme -->
        <item name="alertDialogTheme">@style/MyAlertDialogTheme</item>
    </style>
    
    <style name="MyAlertDialogTheme" parent="@android:style/Theme.Material.Light.Dialog.Alert">
        <item name="android:textAppearanceSmall">@style/MyTextAppearanceSmall</item>
        <item name="android:textAppearanceMedium">@style/MyTextAppearanceMedium</item>
        <item name="android:textAppearanceLarge">@style/MyTextAppearanceLarge</item>
    </style>
    
    <style name="MyTextAppearance" parent="TextAppearance.AppCompat">
        <item name="android:fontFamily">@font/comic_sans</item>
    </style>
    (...)
    

    如果我没记错的话,android:textAppearanceSmall 用于消息,android:textAppearanceMedium 用于标题。但你可以选择任何你想要的,然后删除其余的。

    另一种选择

    在不覆盖alertDialogTheme 的情况下,通过构建器构造函数设置样式。示例:AlertDialog.Builder(getActivity(), R.style.MyAlertDialogTheme)

    【讨论】:

    • 这个时候,这才是真正的答案
    【解决方案6】:

    您可以使用 SpannableString,在其上设置字体并将其返回给 AlertDialog.Builder

    这是一个辅助函数,用于将字体添加到 CharSequence 并返回 SpannableString -

    private static SpannableString typeface(Typeface typeface, CharSequence chars) {
        if (chars == null) {
            return null;
        }
        SpannableString s = new SpannableString(chars);
        s.setSpan(new TypefaceSpan(typeface), 0, s.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        return s;
    }
    

    在文本上设置 TypeFace 的类 -

    public class TypefaceSpan extends MetricAffectingSpan {
    
        private final Typeface typeface;
    
        public TypefaceSpan(Typeface typeface) {
            this.typeface = typeface;
        }
    
        @Override
        public void updateDrawState(TextPaint tp) {
            tp.setTypeface(typeface);
            tp.setFlags(tp.getFlags() | Paint.SUBPIXEL_TEXT_FLAG);
        }
    
        @Override
        public void updateMeasureState(TextPaint p) {
            p.setTypeface(typeface);
            p.setFlags(p.getFlags() | Paint.SUBPIXEL_TEXT_FLAG);
        }
    }
    

    在创建对话框时,您可以像这样用 SpannableString 替换字符串 -

    public static Dialog createDialog(Context c, String title, String message, String pButton, String nButton, AlertCallback callback) {
    
        AlertDialog.Builder builder = new AlertDialog.Builder(c);
    
        builder.setMessage(typeface(Fonts.Regular, message));
        builder.setTitle(typeface(Fonts.Bold, title));
        builder.setPositiveButton(typeface(Fonts.Bold, pButton),callback::onPositiveButtonClick);
        builder.setNegativeButton(typeface(Fonts.Bold, nButton),callback::onNegativeButtonClick);
    
        AlertDialog dialog = builder.create();
        return builder.create();
    } 
    

    我建议将字体加载到缓存中,而不是多次调用 createFromAsset。 希望这会有所帮助!

    【讨论】:

      【解决方案7】:

      我有一个包含项目列表的警报对话框,所以我必须结合几个答案并稍微简化它,这是警报对话框本身的代码:

      val dialog = AlertDialog.Builder(this, R.style.MyAlertDialogTheme).setTitle(R.string.sort_by)
         .setSingleChoiceItems(modelList, selectedSortPosition) { _, position -> selectedSortPosition = position }
         .setPositiveButton(R.string.ok) { _, _ ->  }
         .setNegativeButton(R.string.cancel) { _, _ -> }.create()
      dialog.show()
      setFontsForDialog(dialog)
      

      这里我使用了 Danilo 回答中的样式,但我为此添加了设置主题颜色:

         <style name="MyAlertDialogTheme" parent="Theme.MaterialComponents.DayNight.Dialog.Alert">
            <item name="colorPrimary">@color/colorPrimary</item>
            <item name="colorAccent">@color/colorAccent</item>
            <item name="android:textAppearanceSmall">@style/MyTextAppearanceSmall</item>
            <item name="android:textAppearanceMedium">@style/MyTextAppearanceMedium</item>
            <item name="android:textAppearanceLarge">@style/MyTextAppearanceLarge</item>
         </style>
      

      因为它只改变列表项的字体,所以我添加了这个方法,因为我要在应用程序中多次使用它,所以我为活动本身创建了一个扩展方法:

      private fun Activity.setFontsForDialog(dialog: AlertDialog) {
          val font = ResourcesCompat.getFont(this, R.font.theme_bold_pn)
          dialog.findViewById<TextView>(android.R.id.message)?.typeface = font
          dialog.findViewById<TextView>(android.R.id.button1)?.typeface = font
          dialog.findViewById<TextView>(android.R.id.button2)?.typeface = font
      }
      

      【讨论】:

        【解决方案8】:

        为此,我为 AlertDialog 创建了一个扩展方法 -
        (这适用于 androidx.appcompat:appcompat:1.1.0)

        fun AlertDialog.setTypefaceInDialog(context: Context) {
        
            val regularFont = ResourcesCompat.getFont(context, R.font.regular_font)
            val boldFont = ResourcesCompat.getFont(context, R.font.medium_font)
        
            findViewById<TextView>(androidx.appcompat.R.id.alertTitle)?.typeface = boldFont
            findViewById<TextView>(android.R.id.message)?.typeface = regularFont
            getButton(AlertDialog.BUTTON_POSITIVE).typeface = boldFont
            getButton(AlertDialog.BUTTON_NEGATIVE).typeface = boldFont
        }
        

        【讨论】:

          【解决方案9】:

          如果您使用Material Components,您可以通过清除样式来自定义您的对话框以满足几乎所有需求。例如,我为对话框创建的自定义样式:

              <style name="ThemeOverlay.App.MaterialAlertDialog" parent="ThemeOverlay.MaterialComponents.MaterialAlertDialog">
                  <item name="materialAlertDialogTitleTextStyle"><!--here goes your title text style --></item>
                  <item name="materialAlertDialogBodyTextStyle"><!--here goes your message text style --></item>
                  <item name="colorPrimary"><!--here goes your dialog primary color. e.g. button text color, etc.--></item>
                  <item name="shapeAppearanceOverlay">@style/ShapeAppearance.App.SmallComponent</item> <!-- your custom shape appearance for your dialog. In my case, I am changing corner radius of dialog to rounded 20dp corners-->
                  <item name="colorSurface">@color/white</item>
                  <item name="buttonBarPositiveButtonStyle">@style/Widget.App.Button</item> <!-- your custom positive button style-->
                  <item name="buttonBarNegativeButtonStyle">@style/Widget.App.Button</item> <!-- your custom negtive button style-->
              </style>
          
              <style name="ShapeAppearance.App.SmallComponent" parent="ShapeAppearance.MaterialComponents.SmallComponent">
                  <item name="cornerFamily">rounded</item>
                  <item name="cornerSize">20dp</item>
              </style>
          
              <style name="Widget.App.Button" parent="Widget.MaterialComponents.Button.TextButton.Dialog">
                  <item name="shapeAppearance">@style/ShapeAppearance.App.SmallComponent</item>
                  <item name="android:textAppearance">@style/Roboto.Bold.Small</item>
                  <item name="android:textColor">@color/colorAccent</item>
                  <item name="android:textAllCaps">true</item>
              </style>
          

          最后,在创建对话框时,别忘了设置这个样式:

           MaterialAlertDialogBuilder(this, R.style.ThemeOverlay_App_MaterialAlertDialog)
                      .setMessage("your message")
                      .show()
          

          【讨论】:

            猜你喜欢
            • 2021-04-19
            • 1970-01-01
            • 2015-04-13
            • 1970-01-01
            • 2021-05-31
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多