Is it possible to have multiple styles inside a TextView?

后端 未结 18 1868
醉梦人生
醉梦人生 2020-11-21 17:34

Is it possible to set multiple styles for different pieces of text inside a TextView?

For instance, I am setting the text as follows:

tv.setText(line         


        
相关标签:
18条回答
  • 2020-11-21 17:57

    If you want to be able to add the styled text in xml you can create a custom view extending TextView and override setText():

    public class HTMLStyledTextView extends TextView
    {
        public HTMLStyledTextView(Context context) {
            super(context);
        }
    
        public HTMLStyledTextView(Context context, AttributeSet attrs) {
            super(context, attrs);
        }
    
        public HTMLStyledTextView(Context context, AttributeSet attrs, int defStyle) {
            super(context, attrs, defStyle);
        }
    
        @Override
        public void setText(CharSequence text, BufferType type)
        {
           super.setText(Html.fromHtml(text.toString()), type);
        }
    }
    

    Then, you can use it like this (replace PACKAGE_NAME with your package name):

    <PACKAGE_NAME.HTMLStyledTextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="<![CDATA[
            <b>Bolded Text:</b> Non-Bolded Text
        ]]>"
    />
    
    0 讨论(0)
  • 2020-11-21 18:00

    Using an auxiliary Spannable Class as Android String Resources shares at the bottom of the webpage. You can approach this by creatingCharSquences and giving them a style.

    But in the example they give us, is just for bold, italic, and even colorize text. I needed to wrap several styles in aCharSequence in order to set them in a TextView. So to that Class (I named it CharSequenceStyles) I just added this function.

    public static CharSequence applyGroup(LinkedList<CharSequence> content){
        SpannableStringBuilder text = new SpannableStringBuilder();
        for (CharSequence item : content) {
            text.append(item);
        }
        return text;
    }
    

    And in the view I added this.

                message.push(postMessageText);
                message.push(limitDebtAmount);
                message.push(pretMessageText);
                TextView.setText(CharSequenceStyles.applyGroup(message));
    

    I hope this help you!

    0 讨论(0)
  • 2020-11-21 18:02

    It is more light weight to use a SpannableString instead of html markup. It helps me to see visual examples so here is a supplemental answer.

    This is a single TextView.

    // set the text
    SpannableString s1 = new SpannableString("bold\n");
    SpannableString s2 = new SpannableString("italic\n");
    SpannableString s3 = new SpannableString("foreground color\n");
    SpannableString s4 = new SpannableString("background color\n");
    SpannableString s5 = new SpannableString("underline\n");
    SpannableString s6 = new SpannableString("strikethrough\n");
    SpannableString s7 = new SpannableString("bigger\n");
    SpannableString s8 = new SpannableString("smaller\n");
    SpannableString s9 = new SpannableString("font\n");
    SpannableString s10 = new SpannableString("URL span\n");
    SpannableString s11 = new SpannableString("clickable span\n");
    SpannableString s12 = new SpannableString("overlapping spans\n");
    
    // set the style
    int flag = Spanned.SPAN_EXCLUSIVE_EXCLUSIVE;
    s1.setSpan(new StyleSpan(Typeface.BOLD), 0, s1.length(), flag);
    s2.setSpan(new StyleSpan(Typeface.ITALIC), 0, s2.length(), flag);
    s3.setSpan(new ForegroundColorSpan(Color.RED), 0, s3.length(), flag);
    s4.setSpan(new BackgroundColorSpan(Color.YELLOW), 0, s4.length(), flag);
    s5.setSpan(new UnderlineSpan(), 0, s5.length(), flag);
    s6.setSpan(new StrikethroughSpan(), 0, s6.length(), flag);
    s7.setSpan(new RelativeSizeSpan(2), 0, s7.length(), flag);
    s8.setSpan(new RelativeSizeSpan(0.5f), 0, s8.length(), flag);
    s9.setSpan(new TypefaceSpan("monospace"), 0, s9.length(), flag);
    s10.setSpan(new URLSpan("https://developer.android.com"), 0, s10.length(), flag);
    s11.setSpan(new ClickableSpan() {
        @Override
        public void onClick(View widget) {
            Toast.makeText(getApplicationContext(), "Span clicked", Toast.LENGTH_SHORT).show();
        }
    }, 0, s11.length(), flag);
    s12.setSpan(new ForegroundColorSpan(Color.RED), 0, 11, flag);
    s12.setSpan(new BackgroundColorSpan(Color.YELLOW), 4, s12.length(), flag);
    s12.setSpan(new UnderlineSpan(), 4, 11, flag);
    
    // build the string
    SpannableStringBuilder builder = new SpannableStringBuilder();
    builder.append(s1);
    builder.append(s2);
    builder.append(s3);
    builder.append(s4);
    builder.append(s5);
    builder.append(s6);
    builder.append(s7);
    builder.append(s8);
    builder.append(s9);
    builder.append(s10);
    builder.append(s11);
    builder.append(s12);
    
    // set the text view with the styled text
    textView.setText(builder);
    // enables clicking on spans for clickable span and url span
    textView.setMovementMethod(LinkMovementMethod.getInstance());
    

    Further Study

    • Explain the meaning of Span flags like SPAN_EXCLUSIVE_EXCLUSIVE
    • Android Spanned, SpannedString, Spannable, SpannableString and CharSequence
    • Types of spans

    This example was originally inspired from here.

    0 讨论(0)
  • 2020-11-21 18:02

    As stated, use TextView.setText(Html.fromHtml(String))

    And use these tags in your Html formatted string:

    <a href="...">
    <b>
    <big>
    <blockquote>
    <br>
    <cite>
    <dfn>
    <div align="...">
    <em>
    <font size="..." color="..." face="...">
    <h1>
    <h2>
    <h3>
    <h4>
    <h5>
    <h6>
    <i>
    <img src="...">
    <p>
    <small>
    <strike>
    <strong>
    <sub>
    <sup>
    <tt>
    <u>
    

    http://commonsware.com/blog/Android/2010/05/26/html-tags-supported-by-textview.html

    0 讨论(0)
  • 2020-11-21 18:06

    In fact, except the Html object, you also could use the Spannable type classes, e.g. TextAppearanceSpan or TypefaceSpan and SpannableString togather. Html class also uses these mechanisms. But with the Spannable type classes, you've more freedom.

    0 讨论(0)
  • 2020-11-21 18:07

    Now the <b> element is deprecated. <strong> renders as <b>, and <em> renders as <i>.

    tv.setText(Html.fromHtml("<strong>bold</strong> and <em>italic</em> "));
    

    this works fine for me

    0 讨论(0)
提交回复
热议问题