【问题标题】:Set different font and color to part of a TextView为 TextView 的一部分设置不同的字体和颜色
【发布时间】:2012-11-14 17:57:09
【问题描述】:

我试过了:

String s = "Some big string"
SpannableStringBuilder sb = new SpannableStringBuilder(s);
//normal font for 1st 9 chars
sb.setSpan(robotoRegular, 0,9,Spannable.SPAN_INCLUSIVE_INCLUSIVE);
//bold font for rest of the chars
sb.setSpan(robotoBold, 9,s.length(),Spannable.SPAN_INCLUSIVE_INCLUSIVE);
//also change color for rest of the chars
sb.setSpan(new ForegroundColorSpan(Color.BLACK), 9,s.length(),Spannable.SPAN_INCLUSIVE_INCLUSIVE);
textView.setText(sb);

但这没有用。

它只需要最新的setSpan,即..,文本颜色正在改变,而不是字体。

【问题讨论】:

  • 你如何定义robotoRegularrobotoBold
  • 类变量:robotoRegular = Typeface.createFromAsset(getAssets(), "fonts/Roboto-Regular.ttf");

标签: android typeface spannablestring


【解决方案1】:

您必须使用TypefaceSpan 而不是Typeface

但由于您使用的是自定义字体,因此您需要扩展 TypefaceSpan

查看这个answer 并创建CustomTypefaceSpan 类。

现在执行以下操作:

Typeface robotoRegular = Typeface.createFromAsset(getAssets(), "fonts/Roboto-Regular.ttf");
Typeface robotoBold = Typeface.createFromAsset(getAssets(), "fonts/Roboto-Bold.ttf");

TypefaceSpan robotoRegularSpan = new CustomTypefaceSpan("", robotoRegular);
TypefaceSpan robotoBoldSpan = new CustomTypefaceSpan("", robotoBold);

// normal font for 1st 9 chars
sb.setSpan(robotoRegularSpan, 0, 9, Spannable.SPAN_INCLUSIVE_INCLUSIVE);
// bold font for rest of the chars
sb.setSpan(robotoBoldSpan, 9, s.length(), Spannable.SPAN_INCLUSIVE_INCLUSIVE);
// also change color for rest of the chars
sb.setSpan(new ForegroundColorSpan(Color.BLUE), 9, s.length(), Spannable.SPAN_INCLUSIVE_INCLUSIVE);
textView.setText(sb);

【讨论】:

    【解决方案2】:

    对于喜欢为此创建 utils 类的人:

    public static SpannableStringBuilder makeTextBold (Activity activity, String string, int fromCharIndex, int toCharIndex) {
        return makeTextBold(activity, new SpannableStringBuilder(string), fromCharIndex, toCharIndex);
    }
    
    public static SpannableStringBuilder makeTextBold (Activity activity, SpannableStringBuilder string, int fromCharIndex, int toCharIndex) {
        SpannableStringBuilder sb = new SpannableStringBuilder(string);
        Typeface bold = Typeface.createFromAsset(activity.getAssets(), "fonts/NexaBold.ttf");
        TypefaceSpan robotoBoldSpan = new CustomTypefaceSpan("", bold);
        sb.setSpan(robotoBoldSpan, fromCharIndex, toCharIndex, Spannable.SPAN_INCLUSIVE_INCLUSIVE);
        return sb;
    }
    
    public static SpannableStringBuilder colorText (int resourceId, String string, Activity activity, int fromCharIndex, int toCharIndex) {
        return colorText(resourceId, new SpannableStringBuilder(string), activity, fromCharIndex, toCharIndex);
    }
    
    public static SpannableStringBuilder colorText (int resourceId, SpannableStringBuilder sb, Activity activity, int fromCharIndex, int toCharIndex) {
        sb.setSpan(new ForegroundColorSpan(activity.getResources().getColor(resourceId)), fromCharIndex, toCharIndex, Spannable.SPAN_INCLUSIVE_INCLUSIVE);
        return sb;
    }
    

    【讨论】:

      【解决方案3】:

      检查此代码:-

      protected void onDraw(Canvas canvas) {
      
              Paint circlePaint = new Paint();
              Typeface mType = Typeface.create(Typeface.SANS_SERIF, Typeface.ITALIC);
              circlePaint.setTextSize(25);
              circlePaint.setColor(Color.RED);
              circlePaint.setTypeface(mType);
              canvas.drawText("Default Typeface", 50, 100, circlePaint);
              //
              circlePaint.setFlags(Paint.UNDERLINE_TEXT_FLAG);
              circlePaint.setColor(Color.YELLOW);
              canvas.drawText("Underline Text Flag", 50, 120, circlePaint);
              //
              circlePaint.setFlags(Paint.STRIKE_THRU_TEXT_FLAG);
              circlePaint.setColor(Color.GREEN);
              canvas.drawText("Strike Thru Text Flag", 50, 140, circlePaint);
              //
              circlePaint.setFlags(Paint.ANTI_ALIAS_FLAG);
              circlePaint.setColor(Color.WHITE);
              canvas.drawText("Anti Alias Flag", 50, 160, circlePaint);
              //
              circlePaint.setFlags(Paint.DEV_KERN_TEXT_FLAG);
              circlePaint.setColor(Color.WHITE);
              canvas.drawText("Dev Kern Text Flag", 50, 180, circlePaint);
              //
              circlePaint.setFlags(Paint.FAKE_BOLD_TEXT_FLAG);
              circlePaint.setColor(Color.CYAN);
              canvas.drawText("Fake Bold Text Flag", 50, 200, circlePaint);
          }
      

      【讨论】:

        【解决方案4】:

        谷歌实际上在this video上给出了官方答复:

        strings.xml

            <string name="test">Hello <annotation font="sans-serif-medium">World!</annotation></string>
        

        在代码中:

        val spannedString = getText(R.string.title) as SpannedString
        val annotations = spannedString.getSpans(0, spannedString.length, Annotation::class.java)
        for (annotation in annotations) {
            if (annotation.key == "font") {
                val fontName = annotation.value
                val typeFace: Typeface = ...
                spannable.setSpan(TypefaceSpan(typeFace), abstract.getSpanStart(annotation),
                        abstract.getSpanEnd(annotation), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
            }
        }
        

        不过,这段代码遗漏了一些重要的事情:如何从字符串中获取字体(尤其是内置的),以及那里的“spannable”和“abstract”是什么。

        如果有人知道如何正确获取这些内容并在此处填写空白,请告诉我。

        【讨论】:

        • 我正在寻找以编程方式使用annotation 标记String 的部分。如果您能提供帮助,不胜感激
        • @Zain 如果您以编程方式执行此操作,则不需要注释。您只需根据需要的位置设置跨度即可。
        • 感谢您的即时反馈.. 我需要做一些自定义的事情,我必须在其中使用自定义 ReplacementSpan .. 问题是它不支持多行文本,除非使用注释
        • @Zain 抱歉,我没怎么用。如果您愿意,我已经在某个字符串中以编程方式制作了一个突出显示文本的示例:stackoverflow.com/a/57534078/878126
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-03-12
        相关资源
        最近更新 更多