具有多个彩色文本的单个TextView


167

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



1
这不是重复的,因为询问者是专门要求颜色的。
Iqbal


我也写了一些库,它的行为与此类似:github.com/ha-yi/MultiColorTextView
Hayi Nukman

Answers:


328

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

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

谢谢也对我有帮助。+1
Hardik Joshi 2012年

10
不要忘记使用来转义用户输入Html.escapeHtml(str)
kelunik 2013年

1
在API级别1
2red13中

3
只是警告。我需要文本大写时遇到问题。我在XML中使用的是android:textAllCaps =“ true”,与此同时,我的HTML内容是大写的。没用 我删除了XML属性,现在可以正常工作了。请注意,因为如果在代码中使用setAllCaps(),则会出现相同的问题。
joao2fast4u 2015年

5
Html.fromHtml(String)现在已弃用,请改用Html.fromHtml(String, Html.FROM_HTML_MODE_LEGACY)更多信息可以在这里找到。
JediBurrell

165

您可以打印多种颜色的行而无需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上的情况
steveh 2014年

如何去约单元测试的TextView,以确保文本两端Color.RED stackoverflow.com/questions/26611533/...
sudocoder

1
对我来说不起作用`java.lang.StringIndexOutOfBoundsException:length = 3; index = 12`
Muhammad Babar

1
StringIndexOutOfBoundsException本身具有解释性。您正在访问超出长度的字符串。
Swapnil Kotwal,2015年

1
我的字符串不是固定的,因此字符串会在应用程序运行时生成。我已经尝试了这个问题的几乎所有答案。但是只有这种解决方案对我有用。
Ms. Sabbir Ahmed

33

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

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

    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)


1
如果需要这种大写字母,只需toUpperCase()字符串即可。
Graeme

33

我这样做是这样的:

查看参考

设置颜色文本传递字符串颜色

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

通过调用以下代码在TextView / Button / EditText等上设置文本

TextView:

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));

完成了


1
nyc one,但HTml.fromHtml已从API 24中弃用
Anuraj R

您可以将呼叫替换Html.fromHtml("...")Html.fromHtml("...", FROM_HTML_MODE_LEGACY)
stkent'4-4-4

31

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

8

嘿,我已经做到了,尝试一下

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文件中,我已经创建了变量并进行了设置,就在我现在正在执行此操作,请在这里输入您的字符串。
阿卜杜勒·里兹万

5

最好在字符串文件中使用字符串,如下所示:

    <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)

4

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

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

这是代码:

我已经使用@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));
    }

2

试试这个:

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

2

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


1

很棒的答案!我能够使用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次-您需要根据使用情况调整数组的颜色/长度!


1
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;

更多信息


1

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


0

2020年6月25日,@ canerkaseler

我想分享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)

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

@canerkaseler

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.