【问题标题】:Change text color of one word in a TextView更改 TextView 中一个单词的文本颜色
【发布时间】:2011-11-05 12:30:51
【问题描述】:

我正在寻找一种方法来从 Activity 中更改 TextView 中单个单词的文本颜色。

例如,这样:

String first = "This word is ";
String next = "red"
TextView t = (TextView) findViewById(R.id.textbox);
t.setText(first + next);

如何将next 文本的颜色更改为红色?

【问题讨论】:

标签: android string colors textview


【解决方案1】:

我知道的最简单的方法就是使用 html。

String first = "This word is ";
String next = "<font color='#EE0000'>red</font>";
t.setText(Html.fromHtml(first + next));

但这将要求您在(如果?)您想要更改颜色时重建 TextView,这可能会造成麻烦。

【讨论】:

  • 这绝对是最简单的方法,但颜色不应该是 color='#EE0000' 需要磅符号来表示十六进制颜色。
  • 已修复,谢谢!我不记得我是从实际代码中复制的还是从内存中复制的,所以它以前可能不起作用。
  • 好的,请确保!此外,我发现您不能使用 8 位十六进制代码,因此没有 alpha 组件。那个让我难过一会。
  • 现在不推荐使用fromHtml
  • Html.fromHtml 已弃用。这个solution 为我工作!
【解决方案2】:
t.setText(first + next, BufferType.SPANNABLE);
Spannable s = (Spannable)t.getText();
int start = first.length();
int end = start + next.length();
s.setSpan(new ForegroundColorSpan(0xFFFF0000), start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

你必须使用 spannable 这也可以让你增加一些文本的大小,使其变得粗体等等......甚至放入一些图像。

【讨论】:

  • 很好的答案,谢谢。在这种情况下,可以使用“s.length()”代替“start + next.length()”:int end = s.length();
  • 万一有人在寻找 Xamarin.Android 解决方案。您可以使用控件的TextFormatted 属性分配SpannableString 对象。
  • 无法正常工作。最终选择了 B K 的解决方案。
  • 1.如果有构建,使用它总是更好。 2. 什么对你不起作用?这个解决方案很旧,很旧,一些 api 已经改变,添加,删除,bug 修复,到底是什么失败了?
  • 我收到java.lang.String cannot be cast to android.text.Spannable 错误。
【解决方案3】:

像这样使用 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);

【讨论】:

  • 有什么我可以替换 new ForegroundColorSpan(Color) 以使文本保留其原始默认颜色吗?
  • 如何在textview中间添加纯文本(字符串)?
【解决方案4】:

对于长字符串,你可以使用这个:

String help = getString(R.string.help);
help = help.replace("some word", "<font color='#EE0000'>some word</font>");
txtDesc.setText(Html.fromHtml(help));

【讨论】:

    【解决方案5】:

    如果您想更改 TextView 文本中特定 String 的所有实例的状态(不区分大小写),您可以像这样使用 StringBuilders 和 SpannableString

    StringBuilder textBuilder = new StringBuilder(myTextView.getText().toString());
    StringBuilder searchedTextBuilder = new StringBuilder((mySearchedString));
    SpannableString spannableString = new SpannableString(myTextView.getText().toString());
    
    int counter = 0;
    int index = 0;
    
    for (int i = 0;i < textBuilder.length() - mySearchedString.length() - 1;i++)
    {
        counter = 0;
        if (Character.toLowerCase(textBuilder.charAt(i)) == Character.toLowerCase(searchedTextBuilder.charAt(index)))
        {
            counter++;
            index++;
            for (int j = 1,z = i + 1;j < mySearchedString.length() - 1;j++,z++)
            {
                if (Character.toLowerCase(textBuilder .charAt(z)) == Character.toLowerCase(searchedTextBuilder .charAt(index)))
                {
                    counter++;
                    index++;
                }
                else
                {
                    index++;
                    if (index % mySearchedString.length() == 0)
                    {
                        index = 0;
                    }
                    break;
                 }
            }
            if (counter == mySearchedString.length() - 1) // A match
            {
                spannableString.setSpan(new ForegroundColorSpan(Color.RED), i,
                                    i + mySearchedString.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); // Do the change you want(In this case changing the fore ground color to red)
                index = 0;
                continue;
            }
            else
            {
                index = 0;
                continue;
            }
        }
    }
    myTextView.setText(spannableString);
    

    }

    • 将整个 TextView 文本存储在 StringBuilder 中。
    • 将搜索到的字符串存储在StringBuilder 中。
    • 将整个 TextView 文本存储在 SpannableString
    • 进行一个简单的操作,查找TextView文本中的所有String实例,并在到达时更改它们。
    • TextView的文本值设置为SpannableString

    【讨论】:

      【解决方案6】:

      我在 Kotlin 中为自己的用例实现了一个实用程序函数,并且可能对其他人有用。

      fun getCusomTextWithSpecificTextWithDiffColor(textToBold: String, fullText: String,
                                                        targetColor: Int) =
                  SpannableStringBuilder(fullText).apply {
                      setSpan(ForegroundColorSpan(targetColor),
                              fullText.indexOf(textToBold),
                              (fullText.indexOf(textToBold) + textToBold.length),
                              Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
                  }
      

      我是如何使用它的:

      context?.let {
              infoMessage.text = AppUtils.getCusomTextWithSpecificTextWithDiffColor(
                      wordAsBold,
                      completeSentence, ContextCompat.getColor(it, R.color.white))
          }
      

      【讨论】:

        【解决方案7】:

        使用:

        makeTextBold("Your order is accepted","accepted", textView);
        makeTextBold("Your order is canceled","canceled", textView);
        

        功能:

        public static void makeTextBold(String sentence, String word, AppCompatTextView textView) {
            SpannableStringBuilder builder = new SpannableStringBuilder();
            int startIndex = sentence.indexOf(word.toLowerCase().trim());
            int endIndex = startIndex + word.toLowerCase().trim().length();
            SpannableString spannableString = new SpannableString(sentence);
            StyleSpan boldSpan = new StyleSpan(Typeface.BOLD);
            spannableString.setSpan(boldSpan, startIndex, endIndex, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); //To make text Bold
            spannableString.setSpan(new ForegroundColorSpan(Color.RED), startIndex, endIndex, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); //To change color of text
            builder.append(spannableString);
            textView.setText(builder, TextView.BufferType.SPANNABLE);
        }
        

        【讨论】:

          【解决方案8】:

          我认为这更具可读性 为字符串中的单词着色 它也可能更有效一点,因为你只写一次

              String str  = YOUR_STRING
              Spannable s = new SpannableString(str);
              int start = str.indexOf(err_word_origin);
              int end =  start + err_word_origin.length();
              s.setSpan(new ForegroundColorSpan(Color.BLUE), start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
              YOUR_TEXT_VIEW.setText(s , TextView.BufferType.SPANNABLE);
          

          【讨论】:

            【解决方案9】:

            我的解决方案扩展:

                fun coloredText(
                baseText: String,
                coloredText: String,
                targetColor: Int
            ): SpannableStringBuilder {
                val transformText = "$baseText $coloredText"
                return SpannableStringBuilder(transformText).apply {
                    setSpan(
                        ForegroundColorSpan(targetColor),
                        transformText.indexOf(coloredText),
                        (transformText.indexOf(coloredText) + coloredText.length),
                        Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
                    )
                }
            }
            

            用法

            binding.mytextView.title = coloredText(
                        baseText = getString(R.string.my_title),
                        coloredText = getString(R.string.my_title_colored_part),
                        targetColor = ContextCompat.getColor(requireContext(), R.color.blue))
            

            【讨论】:

              【解决方案10】:

              我找到了这个最佳答案 https://stackoverflow.com/a/53573169/14250778 只是更改了一行以支持以大写字母开头的单词

              public void setHighLightedText(TextView tv, String textToHighlight) {
                      // added "toLowerCase()" to support words that starts with uppercase letter
                      String tvt = tv.getText().toString().toLowerCase();
                      int ofe = tvt.indexOf(textToHighlight, 0);
                      Spannable wordToSpan = new SpannableString(tv.getText());
                      for (int ofs = 0; ofs < tvt.length() && ofe != -1; ofs = ofe + 1) {
                          ofe = tvt.indexOf(textToHighlight, ofs);
                          if (ofe == -1)
                              break;
                          else {
                              // set color here
                              wordToSpan.setSpan(new BackgroundColorSpan(0xFFFFFF00), ofe, ofe + textToHighlight.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
                              tv.setText(wordToSpan, TextView.BufferType.SPANNABLE);
                          }
                      }
                  }
              

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2016-06-13
                • 2021-05-30
                • 2014-04-28
                • 1970-01-01
                相关资源
                最近更新 更多