【问题标题】:Single TextView with multiple colored text具有多个彩色文本的单个 TextView
【发布时间】:2011-08-30 23:03:34
【问题描述】:

正如标题所说,我想知道是否可以在单个 textview 元素中实现两个不同颜色的字符。

【问题讨论】:

标签: android textview


【解决方案1】:

是的,如果您使用htmlfont-color 属性格式化String,然后将其传递给方法Html.fromHtml(your text here)

String text = "<font color=#cc0029>First Color</font> <font color=#ffcc00>Second Color</font>";
yourtextview.setText(Html.fromHtml(text));

【讨论】:

  • 别忘了使用Html.escapeHtml(str)转义用户输入。
  • 多么可爱的答案....
  • 不错的解决方案.. 但我想问一下它适用于所有 android os 版本吗?
  • 只是一个警告。当我需要我的文本为大写时,我遇到了问题。我在 XML 中使用 android:textAllCaps="true" ,同时我的 HTML 内容是大写的。它没有工作。我删除了 XML 属性,它现在工作正常。小心,因为如果你在代码中使用 setAllCaps() 会出现同样的问题。
  • Html.fromHtml(String) 现在已弃用,请改用 Html.fromHtml(String, Html.FROM_HTML_MODE_LEGACY)More information can be found here.
【解决方案2】:

您可以在没有 HTML 的情况下打印具有多种颜色的行:

TextView textView = (TextView) findViewById(R.id.mytextview01);
Spannable word = new SpannableString("Your message");        

word.setSpan(new ForegroundColorSpan(Color.BLUE), 0, word.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

textView.setText(word);
Spannable wordTwo = new SpannableString("Your new message");        

wordTwo.setSpan(new ForegroundColorSpan(Color.RED), 0, wordTwo.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
textView.append(wordTwo);

【讨论】:

  • 很好,谢谢,BackgroundColorSpan 也可以。您的示例中有一个小错字,WordToSpan 和 WordtoSpan,请注意 To 上的大小写
  • 不为我工作得到` java.lang.StringIndexOutOfBoundsException: length=3;索引=12`
  • StringIndexOutOfBoundsException 本身就是解释性的。您正在访问超出其长度的字符串。
  • 我的字符串不是固定的,所以字符串会在应用程序运行时生成。我已经尝试了几乎所有这个问题的答案。但只有这个解决方案对我有用。
  • 完美的解决方案,简单明了。发布了这个答案的 Kotlin 版本。干杯
【解决方案3】:

我是这样做的:

通过传递字符串colorText

设置颜色

private String getColoredSpanned(String text, String color) {
    String input = "<font color=" + color + ">" + text + "</font>";
    return input;
}

Set text on TextView / Button / EditText 等通过调用以下代码:

文本视图:

TextView txtView = (TextView)findViewById(R.id.txtView);

获取彩色字符串:

String name = getColoredSpanned("Hiren", "#800000");
String surName = getColoredSpanned("Patel","#000080");

在两个不同颜色的字符串的TextView上设置Text:

txtView.setText(Html.fromHtml(name+" "+surName));

完成

【讨论】:

  • nyc one ,但 API 24 已弃用 HTml.fromHtml
  • 您可以将对Html.fromHtml("...")的调用替换为对Html.fromHtml("...", FROM_HTML_MODE_LEGACY)的调用
【解决方案4】:

您可以使用Spannable 将效果应用到您的TextView

这是我为TextView 文本的第一部分着色的示例(同时允许您动态设置颜色,而不是像 HTML 示例那样将其硬编码为字符串!)

    mTextView.setText("Red text is here", BufferType.SPANNABLE);
    Spannable span = (Spannable) mTextView.getText();
    span.setSpan(new ForegroundColorSpan(0xFFFF0000), 0, "Red".length(),
             Spannable.SPAN_INCLUSIVE_EXCLUSIVE);

在此示例中,您可以将 0xFFFF0000 替换为 getResources().getColor(R.color.red)

【讨论】:

  • 如果你需要这个大写,只需 toUpperCase() 字符串。
【解决方案5】:

使用 SpannableStringBuilder

SpannableStringBuilder builder = new SpannableStringBuilder();

SpannableString str1= new SpannableString("Text1");
str1.setSpan(new ForegroundColorSpan(Color.RED), 0, str1.length(), 0);
builder.append(str1);

SpannableString str2= new SpannableString(appMode.toString());
str2.setSpan(new ForegroundColorSpan(Color.GREEN), 0, str2.length(), 0);
builder.append(str2);

TextView tv = (TextView) view.findViewById(android.R.id.text1);
tv.setText( builder, TextView.BufferType.SPANNABLE);

【讨论】:

    【解决方案6】:

    我已经做到了,试试看:

    TextView textView=(TextView)findViewById(R.id.yourTextView);//init
    
    //here I am appending two string into my textView with two diff colors.
    //I have done from fragment so I used here getActivity(), 
    //If you are trying it from Activity then pass className.this or this; 
    
    textView.append(TextViewUtils.getColoredString(getString(R.string.preString),ContextCompat.getColor(getActivity(),R.color.firstColor)));
    textView.append(TextViewUtils.getColoredString(getString(R.string.postString),ContextCompat.getColor(getActivity(),R.color.secondColor)));
    

    在你的 TextViewUtils 类中添加这个方法:

     /***
     *
     * @param mString this will setup to your textView
     * @param colorId  text will fill with this color.
     * @return string with color, it will append to textView.
     */
    public static Spannable getColoredString(String mString, int colorId) {
        Spannable spannable = new SpannableString(mString);
        spannable.setSpan(new ForegroundColorSpan(colorId), 0, spannable.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
        Log.d(TAG,spannable.toString());
        return spannable;
    }
    

    【讨论】:

    • 我刚刚更新,检查一次,它对我有用。
    • Myabe 你用 Html.fromHtml 来使用这个字符串吗?
    • 在 string.xml 文件中我创建了变量并设置了这个,它现在对我有用我正在这样做,你能在这里给出你的字符串吗。
    【解决方案7】:

    最好使用strings文件中的字符串,这样:

        <string name="some_text">
    <![CDATA[
    normal color <font color=\'#06a7eb\'>special color</font>]]>
        </string>
    

    用法:

    textView.text=HtmlCompat.fromHtml(getString(R.string.some_text), HtmlCompat.FROM_HTML_MODE_LEGACY)
    

    【讨论】:

      【解决方案8】:

      @Swapnil Kotwal 答案的 Kotlin 版本。

      Android Studio 4.0.1、Kotlin 1.3.72

      val greenText = SpannableString("This is green,")
      greenText.setSpan(ForegroundColorSpan(resources.getColor(R.color.someGreenColor), null), 0, greenText.length, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
      yourTextView.text = greenText
      
      val yellowText = SpannableString("this is yellow, ")
      yellowText.setSpan(ForegroundColorSpan(resources.getColor(R.color.someYellowColor), null), 0, yellowText.length, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
      yourTextView.append(yellowText)
      
      val redText = SpannableString("and this is red.")
      redText.setSpan(ForegroundColorSpan(resources.getColor(R.color.someRedColor), null), 0, redText.length, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
      yourTextView.append(redText)
      

      【讨论】:

        【解决方案9】:

        我不知道,因为什么时候可以,但是您可以简单地将&lt;font&gt; &lt;/font&gt; 添加到您的 string.xml 中,这将自动更改每个文本的颜色。无需添加任何额外的代码,例如可扩展文本等。

        示例

        <string name="my_formatted_text">
            <font color="#FF0707">THIS IS RED</font>
            <font color="#0B132B">AND NOW BLUE</font>
        </string>
        

        【讨论】:

          【解决方案10】:

          我已经为与这个问题类似的其他问题写了一些代码,但是那个问题被重复了,所以我无法在那里回答,所以如果有人寻找相同的要求,我只是把我的代码放在这里。

          这不是完全有效的代码,您需要进行一些小的更改才能使其正常工作。

          代码如下:

          我使用了@Graeme 使用可扩展文本的想法。

          String colorfulText = "colorfulText";       
              Spannable span = new SpannableString(colorfulText);             
          
              for ( int i = 0, len = colorfulText.length(); i < len; i++ ){
                  span.setSpan(new ForegroundColorSpan(getRandomColor()), i, i+1,Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);                     
              }   
          
              ((TextView)findViewById(R.id.txtSplashscreenCopywrite)).setText(span);
          

          随机颜色法:

            private int getRandomColor(){
                  Random rnd = new Random();
                  return Color.argb(255, rnd.nextInt(256), rnd.nextInt(256), rnd.nextInt(256));
              }
          

          【讨论】:

            【解决方案11】:

            试试这个:

            mBox = new TextView(context);
            mBox.setText(Html.fromHtml("<b>" + title + "</b>" +  "<br />" + 
                  "<small>" + description + "</small>" + "<br />" + 
                  "<small>" + DateAdded + "</small>"));
            

            【讨论】:

              【解决方案12】:

              尽可能使用 SpannableBuilder 类而不是 HTML 格式,因为它比 HTML 格式解析更快。 在Github 上查看我自己的基准测试“SpannableBuilder vs HTML” 谢谢!

              【讨论】:

                【解决方案13】:

                使用 Kotlin 和 Extensions,您可以非常简单、干净地添加彩色文本:

                用这个内容创建一个文件TextViewExtensions.kt

                fun TextView.append(string: String?, @ColorRes color: Int) {
                    if (string == null || string.isEmpty()) {
                        return
                    }
                
                    val spannable: Spannable = SpannableString(string)
                    spannable.setSpan(
                        ForegroundColorSpan(ContextCompat.getColor(context, color)),
                        0,
                        spannable.length,
                        Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
                    )
                
                    append(spannable)
                }
                

                现在添加颜色文本真的很容易

                textView.text = "" // Remove old text
                textView.append("Red Text", R.color.colorAccent)
                textView.append("White Text", android.R.color.white)
                

                基本上与@Abdul Rizwan 答案相同,但使用 Kotlin、扩展、一些验证并在扩展中获取颜色。

                【讨论】:

                  【解决方案14】:

                  Kotlin 答案

                  fun setTextColor(tv:TextView, startPosition:Int, endPosition:Int, color:Int){
                      val spannableStr = SpannableString(tv.text)
                  
                      val underlineSpan = UnderlineSpan()
                      spannableStr.setSpan(
                          underlineSpan,
                          startPosition,
                          endPosition,
                          Spanned.SPAN_INCLUSIVE_EXCLUSIVE
                      )
                  
                      val backgroundColorSpan = ForegroundColorSpan(this.resources.getColor(R.color.agreement_color))
                      spannableStr.setSpan(
                          backgroundColorSpan,
                          startPosition,
                          endPosition,
                          Spanned.SPAN_INCLUSIVE_EXCLUSIVE
                      )
                  
                      val styleSpanItalic = StyleSpan(Typeface.BOLD)
                      spannableStr.setSpan(
                          styleSpanItalic,
                          startPosition,
                          endPosition,
                          Spanned.SPAN_INCLUSIVE_EXCLUSIVE
                      )
                  
                      tv.text = spannableStr
                  }
                  

                  之后,调用上面的函数。您可以调用多个:

                  setTextColor(textView, 0, 61, R.color.agreement_color)
                  setTextColor(textView, 65, 75, R.color.colorPrimary)
                  

                  输出: 你可以看到下划线和不同的颜色。

                  【讨论】:

                  • 你在哪里使用你传递给函数的颜色参数?
                  • 在这里:ForegroundColorSpan(this.resources.getColor(R.color.agreement_color)) -> R.color.agreement_color is "setTextColor(view, int, int, [int color id from your color文件])"
                  • 我的意思是,参数“color”是怎么使用的?
                  • 嗯,好的,我明白了。你可以这样使用:ForegroundColorSpan(this.resources.getColor(color))
                  【解决方案15】:

                  很棒的答案!我能够使用 Spannable 构建彩虹色文本(因此可以对任何颜色数组重复此操作)。如果对任何人有帮助,这是我的方法:

                  private Spannable buildRainbowText(String pack_name) {
                          int[] colors = new int[]{Color.RED, 0xFFFF9933, Color.YELLOW, Color.GREEN, Color.BLUE, Color.RED, 0xFFFF9933, Color.YELLOW, Color.GREEN, Color.BLUE, Color.RED, 0xFFFF9933, Color.YELLOW, Color.GREEN, Color.BLUE, Color.RED, 0xFFFF9933, Color.YELLOW, Color.GREEN, Color.BLUE};
                          Spannable word = new SpannableString(pack_name);
                          for(int i = 0; i < word.length(); i++) {
                              word.setSpan(new ForegroundColorSpan(colors[i]), i, i+1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
                          }
                          return word;
                      }
                  

                  然后我只是 setText(buildRainboxText(pack_name)); 请注意,我传入的所有单词都在 15 个字符以下,这只会重复 5 种颜色 3 次 - 您需要调整数组的颜色/长度以供您使用!

                  【讨论】:

                    【解决方案16】:
                    if (Build.VERSION.SDK_INT >= 24) {
                         Html.fromHtml(String, flag) // for 24 API  and more
                     } else {
                         Html.fromHtml(String) // or for older API 
                     }
                    

                    适用于 24 API 及更多(标志)

                    public static final int FROM_HTML_MODE_COMPACT = 63;
                    public static final int FROM_HTML_MODE_LEGACY = 0;
                    public static final int FROM_HTML_OPTION_USE_CSS_COLORS = 256;
                    public static final int FROM_HTML_SEPARATOR_LINE_BREAK_BLOCKQUOTE = 32;
                    public static final int FROM_HTML_SEPARATOR_LINE_BREAK_DIV = 16;
                    public static final int FROM_HTML_SEPARATOR_LINE_BREAK_HEADING = 2;
                    public static final int FROM_HTML_SEPARATOR_LINE_BREAK_LIST = 8;
                    public static final int FROM_HTML_SEPARATOR_LINE_BREAK_LIST_ITEM = 4;
                    public static final int FROM_HTML_SEPARATOR_LINE_BREAK_PARAGRAPH = 1;
                    public static final int TO_HTML_PARAGRAPH_LINES_CONSECUTIVE = 0;
                    public static final int TO_HTML_PARAGRAPH_LINES_INDIVIDUAL = 1;
                    

                    More Info

                    【讨论】:

                      【解决方案17】:

                      从 API 24 开始,您有了 FROM_HTML_OPTION_USE_CSS_COLORS,因此您可以在 CSS 中定义颜色,而不是一直重复使用 font color=" 更清晰 - 当您有一些 html 并且想要突出显示一些预定义的标签时 - 您只需要在 html 顶部添加 CSS 片段

                      【讨论】:

                        【解决方案18】:

                        为像这样转换您的字符串提供通用功能。

                        //pass param textviewid ,start,end,string
                        //R.color.Red it's your color you can change it as requirement
                        
                        fun SpannableStringWithColor(view: TextView,start:Int,end:Int, s: String) {
                            val wordtoSpan: Spannable =
                                SpannableString(s)
                            wordtoSpan.setSpan(
                                ForegroundColorSpan(ContextCompat.getColor(view.context, R.color.Red)),
                                start,
                                end,
                                Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
                            )
                            view.text = wordtoSpan
                            }
                        

                        我们可以根据需要在任何地方使用。

                         SpannableStringWithColor(tvMobileNo,0,14,"Mobile Number :   " + "123456789")
                        
                         SpannableStringWithColor(tvEmail,0,5,"Email :   " + "abc@gmail.com" "))
                        
                         SpannableStringWithColor(tvAddress,0,8,"Address :   " + "Delhi India")
                        

                        【讨论】:

                          【解决方案19】:

                          Kotlin 中的构建器函数:

                            val text = buildSpannedString {
                                append("My red text")
                                setSpan(
                                    ForegroundColorSpan(ContextCompat.getColor(requireContext(), R.color.red)),
                                    3,
                                    6,
                                    Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
                                )
                            }
                            textView?.setText(text)
                          

                          【讨论】:

                            【解决方案20】:

                            对于科特林:

                            @JvmStatic
                                @BindingAdapter(
                                    "app:txt1",
                                    "app:txt2",
                                    "app:color1",
                                    "app:color2",
                                    requireAll = false
                                )
                                fun setColors(
                                    txtView: AppCompatTextView,
                                    txt1: String,
                                    txt2: String,
                                    color1: Int,
                                    color2: Int
                                ) {
                                    txtView.setColors(txt1 = txt1, txt2 = txt2, color1 = color1, color2)
                                }
                            
                            
                            fun AppCompatTextView.setColors(txt1: String, txt2: String, color1: Int, color2: Int) {
                            
                            
                                    val word: Spannable = SpannableString(txt1)
                            
                                    word.setSpan(
                                        ForegroundColorSpan(ContextCompat.getColor(this.context, color1)),
                                        0,
                                        word.length,
                                        Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
                                    )
                            
                                    this.text = word
                                    val wordTwo: Spannable = SpannableString(txt2)
                            
                                    wordTwo.setSpan(
                                        ForegroundColorSpan(ContextCompat.getColor(this.context, color2)),
                                        0,
                                        wordTwo.length,
                                        Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
                                    )
                                    this.append(wordTwo)
                            
                                }
                            
                            
                            <androidx.appcompat.widget.AppCompatTextView
                                        android:layout_width="match_parent"
                                        android:layout_height="wrap_content"
                                        app:txt1="@{}"
                                        app:txt2="@{}"
                                        app:color1="@{}"
                                        app:color2="@{}" />
                            

                            【讨论】:

                              猜你喜欢
                              • 1970-01-01
                              • 2013-01-25
                              • 2011-11-05
                              • 1970-01-01
                              • 2012-03-17
                              • 1970-01-01
                              • 1970-01-01
                              • 1970-01-01
                              • 1970-01-01
                              相关资源
                              最近更新 更多