在Android中设置TextView span的颜色

是否有可能在TextView中设置文本跨度的颜色?

我想做一些类似于Twitter应用程序的事情,其中一部分文本是蓝色的。见下图:

< p > alt text < br > (来源:twimg.com) < /订阅>

213969 次浏览

设置你的TextView的文本可扩展,并为你的文本定义一个ForegroundColorSpan

TextView textView = (TextView)findViewById(R.id.mytextview01);
Spannable wordtoSpan = new SpannableString("I know just how to whisper, And I know just how to cry,I know just where to find the answers");
wordtoSpan.setSpan(new ForegroundColorSpan(Color.BLUE), 15, 30, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
textView.setText(wordtoSpan);

另一个答案将非常相似,但不需要设置TextView的文本两次

TextView TV = (TextView)findViewById(R.id.mytextview01);


Spannable wordtoSpan = new SpannableString("I know just how to whisper, And I know just how to cry,I know just where to find the answers");


wordtoSpan.setSpan(new ForegroundColorSpan(Color.BLUE), 15, 30, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);


TV.setText(wordtoSpan);

这是一个帮助函数。当你有多种语言的时候非常有用!

private void setColor(TextView view, String fulltext, String subtext, int color) {
view.setText(fulltext, TextView.BufferType.SPANNABLE);
Spannable str = (Spannable) view.getText();
int i = fulltext.indexOf(subtext);
str.setSpan(new ForegroundColorSpan(color), i, i + subtext.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}

有一个用于创建Spannable的工厂,并避免强制转换,就像这样:

Spannable span = Spannable.Factory.getInstance().newSpannable("text");

在某些情况下可以使用的另一种方法是在接受Spannable的视图的属性中设置链接颜色。

例如,如果你的Spannable将用于TextView,你可以在XML中设置链接颜色:

<TextView
android:id="@+id/myTextView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColorLink="@color/your_color"
</TextView>

你也可以在代码中使用:

TextView tv = (TextView) findViewById(R.id.myTextView);
tv.setLinkTextColor(your_color);

如果你想要更多的控制,你可能想检查TextPaint类。下面是如何使用它:

final ClickableSpan clickableSpan = new ClickableSpan() {
@Override
public void onClick(final View textView) {
//Your onClick code here
}


@Override
public void updateDrawState(final TextPaint textPaint) {
textPaint.setColor(yourContext.getResources().getColor(R.color.orange));
textPaint.setUnderlineText(true);
}
};

设置颜色文本通过通过字符串颜色:

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

在TextView上设置文本:

txtView.setText(Html.fromHtml(name));

完成

当我试图理解一个新概念时,我总是发现视觉例子很有帮助。

背景颜色

enter image description here

SpannableString spannableString = new SpannableString("Hello World!");
BackgroundColorSpan backgroundSpan = new BackgroundColorSpan(Color.YELLOW);
spannableString.setSpan(backgroundSpan, 0, spannableString.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
textView.setText(spannableString);

前景颜色

enter image description here

SpannableString spannableString = new SpannableString("Hello World!");
ForegroundColorSpan foregroundSpan = new ForegroundColorSpan(Color.RED);
spannableString.setSpan(foregroundSpan, 0, spannableString.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
textView.setText(spannableString);

结合

enter image description here

SpannableString spannableString = new SpannableString("Hello World!");
ForegroundColorSpan foregroundSpan = new ForegroundColorSpan(Color.RED);
BackgroundColorSpan backgroundSpan = new BackgroundColorSpan(Color.YELLOW);
spannableString.setSpan(foregroundSpan, 0, 8, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
spannableString.setSpan(backgroundSpan, 3, spannableString.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
textView.setText(spannableString);

进一步的研究

  1. 创建文本视图在你的布局
  2. 粘贴此代码在你的MainActivity

    TextView textview=(TextView)findViewById(R.id.textviewid);
    Spannable spannable=new SpannableString("Hello my name is sunil");
    spannable.setSpan(new ForegroundColorSpan(Color.BLUE), 0, 5,
    Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
    textview.setText(spannable);
    //Note:- the 0,5 is the size of colour which u want to give the strring
    //0,5 means it give colour to starting from h and ending with space i.e.(hello), if you want to change size and colour u can easily
    
String text = "I don't like Hasina.";
textView.setText(spannableString(text, 8, 14));


private SpannableString spannableString(String text, int start, int end) {
SpannableString spannableString = new SpannableString(text);
ColorStateList redColor = new ColorStateList(new int[][]{new int[]{}}, new int[]{0xffa10901});
TextAppearanceSpan highlightSpan = new TextAppearanceSpan(null, Typeface.BOLD, -1, redColor, null);


spannableString.setSpan(highlightSpan, start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
spannableString.setSpan(new BackgroundColorSpan(0xFFFCFF48), start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
spannableString.setSpan(new RelativeSizeSpan(1.5f), start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);


return spannableString;
}

输出:

enter image description here

只是补充一下已接受的答案,因为所有的答案似乎只讨论android.graphics.Color:如果我想要的颜色是在res/values/colors.xml中定义的呢?

例如,考虑在colors.xml中定义的材质设计颜色:

<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="md_blue_500">#2196F3</color>
</resources>

(android_material_design_colours.xml是你最好的朋友)

然后在使用Color.BLUE的地方使用ContextCompat.getColor(getContext(), R.color.md_blue_500),这样:

wordtoSpan.setSpan(new ForegroundColorSpan(Color.BLUE), 15, 30, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

就变成:

wordtoSpan.setSpan(new ForegroundColorSpan(ContextCompat.getColor(getContext(), R.color.md_blue_500)), 15, 30, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

我发现:

这是一个Kotlin扩展函数

    fun TextView.setColouredSpan(word: String, color: Int) {
val spannableString = SpannableString(text)
val start = text.indexOf(word)
val end = text.indexOf(word) + word.length
try {
spannableString.setSpan(ForegroundColorSpan(color), start, end,Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
text = spannableString
} catch (e: IndexOutOfBoundsException) {
println("'$word' was not not found in TextView text")
}
}

使用它后,你已经设置你的文本到TextView,就像这样

private val blueberry by lazy { getColor(R.color.blueberry) }


textViewTip.setColouredSpan("Warning", blueberry)

下面的内容非常适合我

    tvPrivacyPolicy = (TextView) findViewById(R.id.tvPrivacyPolicy);
String originalText = (String)tvPrivacyPolicy.getText();
int startPosition = 15;
int endPosition = 31;


SpannableString spannableStr = new SpannableString(originalText);
UnderlineSpan underlineSpan = new UnderlineSpan();
spannableStr.setSpan(underlineSpan, startPosition, endPosition, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);


ForegroundColorSpan backgroundColorSpan = new ForegroundColorSpan(Color.BLUE);
spannableStr.setSpan(backgroundColorSpan, startPosition, endPosition, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);


StyleSpan styleSpanItalic  = new StyleSpan(Typeface.BOLD);


spannableStr.setSpan(styleSpanItalic, startPosition, endPosition, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);


tvPrivacyPolicy.setText(spannableStr);

以上代码的输出

enter image description here

这里有些答案不是最新的。因为,您将(在大多数情况下)在链接上添加一个自定义的clic操作

此外,根据文档帮助,你的跨接字符串链接颜色将有一个默认颜色。 默认的链接颜色是主题的强调色或android:textColorLink,如果这个属性是在主题中定义的

这里有一种安全的方法。

 private class CustomClickableSpan extends ClickableSpan {


private int color = -1;


public CustomClickableSpan(){
super();
if(getContext() != null) {
color = ContextCompat.getColor(getContext(), R.color.colorPrimaryDark);
}
}


@Override
public void updateDrawState(@NonNull TextPaint ds) {
ds.setColor(color != -1 ? color : ds.linkColor);
ds.setUnderlineText(true);
}


@Override
public void onClick(@NonNull View widget) {
}
}

然后使用它。

   String text = "my text with action";
hideText= new SpannableString(text);
hideText.setSpan(new CustomClickableSpan(){


@Override
public void onClick(@NonNull View widget) {
// your action here !
}


}, 0, text.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
yourtextview.setText(hideText);
// don't forget this ! or this will not work !
yourtextview.setMovementMethod(LinkMovementMethod.getInstance());

希望这对你有很大帮助!

从开发人员文档中,更改一个可伸缩对象的颜色和大小:

1-创建类:

    class RelativeSizeColorSpan(size: Float,@ColorInt private val color: Int): RelativeSizeSpan(size) {


override fun updateDrawState(textPaint: TextPaint?) {
super.updateDrawState(textPaint)
textPaint?.color = color
}
}

2 .使用该类创建你的spannable:

    val spannable = SpannableStringBuilder(titleNames)
spannable.setSpan(
RelativeSizeColorSpan(1.5f, Color.CYAN), // Increase size by 50%
titleNames.length - microbe.name.length, // start
titleNames.length, // end
Spannable.SPAN_EXCLUSIVE_INCLUSIVE
)

Textview Span

使用kotlin-ktx,您可以轻松实现这一点

        bindView?.oneTimePasswordTitle?.text = buildSpannedString {
append("One Time Password ")
inSpans(
ForegroundColorSpan(ContextCompat.getColor(bindView?.oneTimePasswordTitle?.context!!,R.color.colorPrimaryText))
){
append(" (As Registered Email)")
}


}

您可以在Kotlin中使用扩展函数

fun CharSequence.colorizeText(
textPartToColorize: CharSequence,
@ColorInt color: Int
): CharSequence = SpannableString(this).apply {
val startIndexOfText = this.indexOf(textPartToColorize.toString())
setSpan(ForegroundColorSpan(color), startIndexOfText, startIndexOfText.plus(textPartToColorize.length), 0)
}

用法:

val colorizedText = "this text will be colorized"
val myTextToColorize = "some text, $colorizedText continue normal text".colorizeText(colorizedText,ContextCompat.getColor(context, R.color.someColor))
viewBinding.myTextView.text = myTextToColorize

现在您可以使用CodeView库轻松地突出显示不同颜色的模式,例如,用您只需要编写的蓝色突出显示文本中的所有url

CodeView codeView = findViewById(R.id.codeview);
codeView.addSyntaxPattern(Patterns.WEB_URL, Color.BLUE);
codeView.setTextHighlighted(text);

CodeView存储库URL: https://github.com/amrdeveloper/codeview

  • 我也有同样的问题。
  • @Dano的回答绝对正确。但这对我没用。
  • 之后,我发现问题,我已经添加ClickableSpan。它会把我的颜色改成另一种颜色(强调色)

问题


当你在ForegroundColorSpanUnderlineSpan之后添加ClickableSpan时,SpannableStringBuilder将不会改变颜色和undline。

解决方案


1. 与ClickableSpan

  • 你可以覆盖ClickableSpan中的updateDrawState方法。
  • 在updateDrawState方法中,您应该删除超级回调。
  • 之后,您应该根据需要修改您的文本绘制。 李enter image description here < / >

2. 没有ClickableSpan

  • 添加ForegroundColorSpan来改变文本颜色
  • Add UnderlineSpan在文本中添加下划线。 李enter image description here < / >
First Part **Second Part should be Bold** last Part

此文本应该使用SpannableString进行更改

import android.graphics.Typeface.BOLD
import android.text.Spannable
import android.text.Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
import android.text.SpannableString
import android.text.style.BackgroundColorSpan
import android.text.style.ForegroundColorSpan
import android.text.style.StyleSpan


val firstPart = "First Part  "
val secondPart = "Second Part should be Bold"
val thirdPart = "  last Part"
val finalString = firstPart + secondPart + thirdPart


val sb: Spannable = SpannableString(finalString).also {
// ... Change text Colour
it.setSpan(
ForegroundColorSpan(getColor(requireContext(), R.color.pink)),
finalString.indexOf(secondPart),
finalString.indexOf(secondPart) + secondPart.length,
SPAN_EXCLUSIVE_EXCLUSIVE
)
// ... Make the text Bold
it.setSpan(
StyleSpan(BOLD),
finalString.indexOf(secondPart),
finalString.indexOf(secondPart) + secondPart.length,
SPAN_EXCLUSIVE_EXCLUSIVE
)
// ... Change Background Colour
it.setSpan(
BackgroundColorSpan(getColor(requireContext(), R.color.lightPink)),
finalString.indexOf(secondPart) - 1,
finalString.indexOf(secondPart) + secondPart.length + 1,
SPAN_EXCLUSIVE_EXCLUSIVE
)
}


yourTextView.text = sb