【问题标题】:Apply two different font styles to a TextView将两种不同的字体样式应用于 TextView
【发布时间】:2012-03-26 00:07:46
【问题描述】:

我想将两种不同的字体样式应用于单个 TextView 中的文本。

我的情况和Android - two sentences, two styles, one TextView一样。唯一的区别是我想在整个文本上设置自定义字体。我已将 Helvetica 字体作为资产包含在我的项目中,并希望将该字体应用于 TextView,文本的第一部分将是 Helvetica BOLD,其余部分是 Helvetica NORMAL。有什么建议吗?

需要以下格式的文本。具有不同样式和单个文本视图的自定义文本。

【问题讨论】:

  • ,为什么你不能使用两个不同字体样式的不同文本视图。
  • @SenthilMg 您可以在问题的参考链接上看到原因。它不会按要求格式化文本
  • ,我猜想通过使用正则表达式将完整的字符串分成两部分:并在不同的文本视图上设置例如:String text = AAAA:BBBBB,String[] splitText = text.split(": "); tv1.setText(splitText[0]);tv2.setText(splitText[1]);

标签: android fonts styles textview


【解决方案1】:

一种方法是扩展TypefaceSpan:

import android.graphics.Paint;
import android.graphics.Typeface;
import android.text.TextPaint;
import android.text.style.TypefaceSpan;

    public class CustomTypefaceSpan extends TypefaceSpan {
        private final Typeface newType;

        public CustomTypefaceSpan(String family, Typeface type) {
            super(family);
            newType = type;
        }

        @Override
        public void updateDrawState(TextPaint ds) {
            applyCustomTypeFace(ds, newType);
        }

        @Override
        public void updateMeasureState(TextPaint paint) {
            applyCustomTypeFace(paint, newType);
        }

        private static void applyCustomTypeFace(Paint paint, Typeface tf) {
            int oldStyle;
            Typeface old = paint.getTypeface();
            if (old == null) {
                oldStyle = 0;
            } else {
                oldStyle = old.getStyle();
            }

            int fake = oldStyle & ~tf.getStyle();
            if ((fake & Typeface.BOLD) != 0) {
                paint.setFakeBoldText(true);
            }

            if ((fake & Typeface.ITALIC) != 0) {
                paint.setTextSkewX(-0.25f);
            }

            paint.setTypeface(tf);
        }
    }

然后当你想使用两种不同的字体调用:

String firstWord = "first ";
String secondWord = "second";

// Create a new spannable with the two strings
Spannable spannable = new SpannableString(firstWord+secondWord);

// Set the custom typeface to span over a section of the spannable object
spannable.setSpan( new CustomTypefaceSpan("sans-serif",CUSTOM_TYPEFACE), 0, firstWord.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
spannable.setSpan( new CustomTypefaceSpan("sans-serif",SECOND_CUSTOM_TYPEFACE), firstWord.length(), firstWord.length() + secondWord.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

// Set the text of a textView with the spannable object
textView.setText( spannable );

【讨论】:

  • 感谢劳伦斯的回答。我正在尝试这个,让我们看看结果会怎样。也让我尝试了解您提供的代码 sn-p 中发生了什么))
  • 没问题,我对关于扩展 TypefaceSpan 名称的第二个代码块做了一些小的改动。在实现方面,CustomTypefaceSpan 已准备就绪,您只需将其添加到您的项目中。第二个代码块是您需要编辑的。
  • 劳伦斯适合我。这个问题似乎很小,但解决方案有点复杂。感谢您的帮助,真正节省了我的时间。
  • 嗨,我在这里发布了一个相关问题stackoverflow.com/questions/17744664/… 我想知道我可以在我的文本上应用任何跨度以使用上述自定义字体,请看看我的问题并帮助我
  • 这里有一个小错误:在你有 secondWord.length() 的地方,它应该是整个组合字符串的长度,而不仅仅是第二个单词的长度。否则,您很可能会收到 IndexOutOfBoundsException
【解决方案2】:

这里有一个更直接的解决方案,你可以使用HTML在同一个TextView上设置不同的样式。

例如:

// Styled label
String styledText = "<big><b><font color='#333333'>title</font></b></big> <small><b><font color='#CC5490'>subtitle</font></b></small>";

// Apply the styled label on the TextView
textView.setText(Html.fromHtml(styledText));

您需要以下导入:

import android.text.Html;

【讨论】:

    【解决方案3】:

    这可能有效 - 创建您自己的自定义 TextView,然后在其中的一部分上使用 StyleSpan:

    public class CustomTextView extends TextView {
    
        public CustomTextView(Context context, AttributeSet attrs) {
            super(context, attrs);
        }
    
        @Override
        public void setTypeface(Typeface tf, int style) {
            if (style == 1){
                //replace "HelveticaBOLD.otf" with the name of your bold font
                tf = Typeface.createFromAsset(getContext().getApplicationContext().getAssets(), "HelveticaBOLD.otf");
            }else{
                //replace "HelveticaNORMAL.otf" with the name of your normal font
                tf = Typeface.createFromAsset(getContext().getApplicationContext().getAssets(), "HelveticaNORMAL.otf");
            }
            super.setTypeface(tf, 0);
        }
    }
    

    然后你可以这样做:

    int index1 = 0; //wherever bold should begin
    int index2 = 5; //wherever bold should end
    
    Spannable span = new SpannableString("some string");
    span.setSpan(new StyleSpan(Typeface.BOLD),index1, index2,Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
    
    ((CustomTextView)findViewById(R.id.yourTextView)).setText(span);
    

    【讨论】:

    • 正是我想要的,谢谢
    • 找不到我的字体资源
    【解决方案4】:

    您可以使用 canvas.drawText 方法创建自定义视图并使用两个 Paint 对象渲染文本

    【讨论】:

      【解决方案5】:

      字体跨度 - 例如,让我们考虑一个带有 android:textStyle="italic" 的 TextView 和一个基于资源中的字体创建的字体,具有粗体样式。当应用基于字体的 TypefaceSpan 时,文本将仅保持粗体样式,覆盖 TextView 的 textStyle。应用基于字体系列的 TypefaceSpan 时:“等宽”,生成的文本将保持斜体样式。

      https://developer.android.com/reference/android/text/style/TypefaceSpan?

      【讨论】:

        【解决方案6】:

        在应用可扩展文本之前,您是否尝试在 TextView 上设置自定义字体?

        Typeface face = Typeface.createFromAsset(ctx.getAssets(), "fonts/boost.ttf")
        TextView tv = (TextView) ctx.findViewById(id);
        tv.setTypeface(face);
        

        然后从链接的问题中应用 SpannableStringBuilder - 我只是假设如果您的 ttf 支持“正常”和“粗体”,它将相应地呈现:)

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-06-18
          相关资源
          最近更新 更多