【发布时间】:2011-08-30 23:03:34
【问题描述】:
正如标题所说,我想知道是否可以在单个 textview 元素中实现两个不同颜色的字符。
【问题讨论】:
-
它不是重复的,因为提问者专门要求颜色。
-
我也写了一些类似行为的库:github.com/ha-yi/MultiColorTextView
正如标题所说,我想知道是否可以在单个 textview 元素中实现两个不同颜色的字符。
【问题讨论】:
是的,如果您使用html 的font-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)转义用户输入。
Html.fromHtml(String) 现在已弃用,请改用 Html.fromHtml(String, Html.FROM_HTML_MODE_LEGACY)。 More information can be found here.
您可以在没有 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);
【讨论】:
我是这样做的:
通过传递字符串和color在Text上设置颜色:
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));
完成
【讨论】:
Html.fromHtml("...")的调用替换为对Html.fromHtml("...", FROM_HTML_MODE_LEGACY)的调用
您可以使用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)
【讨论】:
使用 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);
【讨论】:
我已经做到了,试试看:
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;
}
【讨论】:
最好使用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)
【讨论】:
@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)
【讨论】:
我不知道,因为什么时候可以,但是您可以简单地将<font> </font> 添加到您的 string.xml 中,这将自动更改每个文本的颜色。无需添加任何额外的代码,例如可扩展文本等。
<string name="my_formatted_text">
<font color="#FF0707">THIS IS RED</font>
<font color="#0B132B">AND NOW BLUE</font>
</string>
【讨论】:
我已经为与这个问题类似的其他问题写了一些代码,但是那个问题被重复了,所以我无法在那里回答,所以如果有人寻找相同的要求,我只是把我的代码放在这里。
这不是完全有效的代码,您需要进行一些小的更改才能使其正常工作。
代码如下:
我使用了@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));
}
【讨论】:
试试这个:
mBox = new TextView(context);
mBox.setText(Html.fromHtml("<b>" + title + "</b>" + "<br />" +
"<small>" + description + "</small>" + "<br />" +
"<small>" + DateAdded + "</small>"));
【讨论】:
尽可能使用 SpannableBuilder 类而不是 HTML 格式,因为它比 HTML 格式解析更快。 在Github 上查看我自己的基准测试“SpannableBuilder vs HTML” 谢谢!
【讨论】:
使用 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、扩展、一些验证并在扩展中获取颜色。
【讨论】:
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)
输出: 你可以看到下划线和不同的颜色。
【讨论】:
很棒的答案!我能够使用 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 次 - 您需要调整数组的颜色/长度以供您使用!
【讨论】:
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;
【讨论】:
从 API 24 开始,您有了 FROM_HTML_OPTION_USE_CSS_COLORS,因此您可以在 CSS 中定义颜色,而不是一直重复使用 font color="
更清晰 - 当您有一些 html 并且想要突出显示一些预定义的标签时 - 您只需要在 html 顶部添加 CSS 片段
【讨论】:
为像这样转换您的字符串提供通用功能。
//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")
【讨论】:
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)
【讨论】:
对于科特林:
@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="@{}" />
【讨论】: