You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让自定义Heebo字体在TextView中支持加粗或配置多字体?

Hey there! Let's fix that Heebo font bold issue you're dealing with. I’ve got two solid solutions for you—first the proper, official way to set up multiple font weights (this is the recommended approach), then the custom function approach you asked about.

The root cause of your problem is that you’re only loading a single regular font file, so Android can’t find a bold variant to use when you set textStyle="bold". Setting up a font family tells Android which font files correspond to which weights, so it can automatically switch between them.

Here's how to do it:

  1. Add all Heebo font files to your project
    Create a res/font directory (if it doesn’t exist already) and drop in your heebo-regular.ttf, heebo-bold.ttf, and any other weight files (like light, medium) you have.

  2. Create a font family XML file
    In the res/font folder, make a new file named heebo_font_family.xml with this content:

    <?xml version="1.0" encoding="utf-8"?>
    <font-family xmlns:android="http://schemas.android.com/apk/res/android">
        <!-- Regular weight (400 is standard for regular) -->
        <font
            android:fontStyle="normal"
            android:fontWeight="400"
            android:font="@font/heebo_regular" />
        <!-- Bold weight (700 is standard for bold) -->
        <font
            android:fontStyle="normal"
            android:fontWeight="700"
            android:font="@font/heebo_bold" />
        <!-- Add other weights here if you have them, e.g., 300 for light, 500 for medium -->
    </font-family>
    
  3. Use the font family in your TextView

    • In XML:
      <TextView
          android:layout_width="wrap_content"
          android:layout_height="wrap_content"
          android:text="Regular text here, and *this is bold text*"
          android:textStyle="bold"
          android:fontFamily="@font/heebo_font_family" />
      
    • In Kotlin/Java:
      // Load the font family
      val heeboFamily = ResourcesCompat.getFont(context, R.font.heebo_font_family)
      // Apply it to the TextView, with bold style
      textView.typeface = Typeface.create(heeboFamily, Typeface.BOLD)
      

Now when you set textStyle="bold" or use Typeface.BOLD, Android will automatically pull the heebo-bold.ttf file instead of sticking with regular.

Solution 2: Custom Function to Detect Bold Styles and Switch Fonts

If for some reason you can’t use a font family, you can write a function to check if the TextView is set to bold and load the corresponding font. This also works if you have mixed bold/regular text in a single TextView (using SpannableStrings).

Case 1: Whole TextView is bold (set via textStyle)

Use this function to check the TextView's style and load the right font:

fun applyHeeboFont(textView: TextView) {
    val context = textView.context
    // Check if the TextView is set to bold
    val isBold = textView.textStyle and Typeface.BOLD != 0 || 
                 textView.typeface?.isBold == true
    
    // Load the appropriate font
    val fontRes = if (isBold) R.font.heebo_bold else R.font.heebo_regular
    textView.typeface = ResourcesCompat.getFont(context, fontRes)
}

Case 2: Mixed bold/regular text (SpannableString)

If you have parts of the text styled as bold (using StyleSpan), you’ll need to replace those spans with custom spans that use your Heebo bold font. Here’s how:

First, create a custom TypefaceSpan to apply your custom font:

class CustomHeeboSpan(private val typeface: Typeface?) : MetricAffectingSpan() {
    override fun updateDrawState(ds: TextPaint) {
        applyTypeface(ds)
    }

    override fun updateMeasureState(paint: TextPaint) {
        applyTypeface(paint)
    }

    private fun applyTypeface(paint: Paint) {
        val oldTypeface = paint.typeface
        val oldStyle = oldTypeface?.style ?: 0

        // Keep existing styles like italic if present
        val fakeStyle = oldStyle and (typeface?.style?.inv() ?: 0)
        if (fakeStyle and Typeface.BOLD != 0) paint.isFakeBoldText = true
        if (fakeStyle and Typeface.ITALIC != 0) paint.textSkewX = -0.25f

        paint.typeface = typeface
    }
}

Then use this function to process the TextView's text:

fun applyHeeboFontWithSpans(textView: TextView) {
    val context = textView.context
    val originalText = textView.text ?: return
    if (originalText !is Spannable) {
        // If it's not a Spannable, just apply the regular/bold font
        applyHeeboFont(textView)
        return
    }

    // Find all StyleSpan instances that are bold
    val boldSpans = originalText.getSpans(0, originalText.length, StyleSpan::class.java)
        .filter { it.style == Typeface.BOLD }

    for (span in boldSpans) {
        val start = originalText.getSpanStart(span)
        val end = originalText.getSpanEnd(span)
        val flags = originalText.getSpanFlags(span)

        // Replace the StyleSpan with our custom Heebo bold span
        val boldFont = ResourcesCompat.getFont(context, R.font.heebo_bold)
        originalText.setSpan(CustomHeeboSpan(boldFont), start, end, flags)
        originalText.removeSpan(span)
    }

    // Set the default font to regular for non-bold text
    textView.typeface = ResourcesCompat.getFont(context, R.font.heebo_regular)
    textView.text = originalText
}

When to use this approach?

This is useful if you’re dealing with dynamic text that has inline bold styling, but keep in mind the font family method is more maintainable and aligns with Android's best practices.


内容的提问来源于stack exchange,提问作者Bar Kozlovski

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 06:42:46