簡體   English   中英

如何在android中為警報對話框設置自定義字體?

[英]How to set custom font for alert dialog in android?

在我的 android 應用程序中,單擊按鈕后會出現一個警報對話框。 我想為警報設置自定義字體 我在網上搜索並找到了一些關於這個主題的教程和問題,但沒有一個對我有用。

如何更改字體?

謝謝

為此,您可以使用警報構建器來構建警報。 然后,您從此警報中獲取 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); 

以上答案對我不起作用。

我使用了以下方法

// 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

我知道這是一個老問題,但我把它留在這里給那些仍在尋找解決方案的人。

如果你只想要更改文本格式,你可以重寫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)

如果您正在使用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()

您可以定義自己想要顯示的對話框的布局。

這是一個鏈接

在 Android 中創建自定義對話框

在您的布局中,您可以使用您想要的字體定義 TextViews。 您需要下載所需字體的 otf 文件。 將它們放在您的資產目錄中。 並將其設置為 TextView 的 TypeFace。 以及如何設置字體

這可能會有所幫助

如何更改 TextView 上的字體?

自定義警報對話框標題文本視圖

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

您可以使用 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。 希望這可以幫助!

我有一個包含項目列表的警報對話框,所以我必須結合幾個答案並稍微簡化它,這是警報對話框本身的代碼:

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
}

為此,我為 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
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM