突出显示文本视图中的文本
highlight text inside a textview
我有一个带有随机背景颜色的 TextView(实际上可以是任何颜色)。我在这个 Textview 上也有一段文本需要可读。
我认为最好的解决方案是用白色突出显示所述文本并将文本颜色设置为黑色。
我的问题是:是否可以从 XML 中突出显示 texview 中的文本?
我的布局中有以下内容:
<TextView
android:layout_width="100dp"
android:layout_height="100dp"
android:id="@+id/colorButton4"
android:layout_gravity="right|bottom"
android:background="@drawable/layout_border"
android:layout_marginRight="30dp"
android:layout_marginBottom ="30dp"
android:clickable="true"
android:onClick="onClick"
android:gravity="center"
android:textColorHighlight="@color/bgWhite"
android:textColor="@color/Black"
android:text="5431354" />
但它不会突出显示文本。
如果您查看了 TextView 的文档,您会发现 android:textColorHighlight
没有按照您的意愿执行:https://developer.android.com/reference/android/widget/TextView.html#attr_android:textColorHighlight
仅在选择文本时使用,例如在 EditText 中。您需要将TextView的背景设置为"hightlight"它。
您可能想为此使用 SpannableString,它允许字符串的各个部分在 TextView 中以不同方式呈现。
像这样:
SpannableString str = new SpannableString("Highlighted. Not highlighted.");
str.setSpan(new BackgroundColorSpan(Color.YELLOW), 0, 11, 0);
textView.setText(str);
要突出显示所有出现的特定文本,请使用此方法:
private void highlightString(String input) {
//Get the text from text view and create a spannable string
SpannableString spannableString = new SpannableString(mTextView.getText());
//Get the previous spans and remove them
BackgroundColorSpan[] backgroundSpans = spannableString.getSpans(0, spannableString.length(), BackgroundColorSpan.class);
for (BackgroundColorSpan span: backgroundSpans) {
spannableString.removeSpan(span);
}
//Search for all occurrences of the keyword in the string
int indexOfKeyword = spannableString.toString().indexOf(input);
while (indexOfKeyword > 0) {
//Create a background color span on the keyword
spannableString.setSpan(new BackgroundColorSpan(Color.YELLOW), indexOfKeyword, indexOfKeyword + input.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
//Get the next index of the keyword
indexOfKeyword = spannableString.toString().indexOf(input, indexOfKeyword + input.length());
}
//Set the final text on TextView
mTextView.setText(spannableString);}
注意:mTextView 是您要在其中突出显示文本的 TextView 对象
简单的方法
您可以使用 Spannable class 来格式化文本。
textView.setText("Hello, I am Awesome, Most Awesome"); // set text first
setHighLightedText(textView, "a"); // highlight all `a` in TextView
输出将类似于下图。
方法在这里
/**
* use this method to highlight a text in TextView
*
* @param tv TextView or Edittext or Button (or derived from TextView)
* @param textToHighlight Text to highlight
*/
public void setHighLightedText(TextView tv, String textToHighlight) {
String tvt = tv.getText().toString();
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);
}
}
}
您可以 获得可点击的高亮文本。
我写了一个 Kotlin 方法,它将突出显示 String
中所有出现的所有关键字,并且 return SpannableString
.
fun main() {
textView.text = highlightKeywords(
highlightColor = ContextCompat.getColor(context, R.color.colorAccent),
message = "Hello World, and Hello to all my Hello Friends.",
keywords = listOf("Hello")
)
}
fun highlightKeywords(
highlightColor: Int,
message: String,
keywords: List<String>,
): SpannableString {
val spannableString = SpannableString(message)
keywords.forEach { keyword ->
if (!keyword.isBlank()) {
var startIndex = message.indexOf(keyword)
while (startIndex >= 0) {
spannableString.setSpan(
ForegroundColorSpan(highlightColor),
startIndex,
startIndex + keyword.length,
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
)
startIndex = message.indexOf(keyword, startIndex + keyword.length)
}
}
}
return spannableString
}
在 Android 上工作了 4 年后,我可以 有把握地说,没有 XML 之外的代码是不可能的。
如果您可以使用一些代码,那么其他人共享的解决方案将对您有所帮助,所以请阅读!
编辑:我选择了一个有效的新答案,但它需要对自定义 TextView 进行编码!
is great and works, but has 2 missing components. First, it will not highlight the first word (as Rany 评论)其次,它不忽略大小写,因此在此字符串中搜索 "test"
:"This is a Test"
将找不到任何内容。
这是我更新的答案,它通过传递的参数解决了这两个问题,并且还添加了 alpha,以防您想使用自定义颜色突出显示。请注意,重载的第一个方法是一个示例,用于说明如何 return 除了第一个被选中的项目之外,之前的方法做了什么。
/**
* Use this method to get the same return as the previous method
*/
public static SpannableString buildHighlightString(String originalText, String textToHighlight){
return buildHighlightString(originalText, textToHighlight, false, Color.YELLOW, 1.0F);
}
/**
* Build a spannable String for use in highlighting text colors
*
* @param originalText The original text that is being highlighted
* @param textToHighlight The text / query that determines what to highlight
* @param ignoreCase Whether or not to ignore case. If true, will ignore and "test" will have
* the same return as "TEST". If false, will return an item as highlighted
* only if it matches it case specficic.
* @param highlightColor The highlight color to use. IE {@link Color#YELLOW} || {@link Color#BLUE}
* @param colorAlpha Alpha to adjust how transparent the color is. 1.0 means it looks exactly
* as it should normally where as 0.0 means it is completely transparent and
* see-through. 0.5 means it is 50% transparent. Useful for darker colors
*/
public static SpannableString buildHighlightString(String originalText, String textToHighlight,
boolean ignoreCase, @ColorInt int highlightColor,
@FloatRange(from = 0.0, to = 1.0) float colorAlpha){
SpannableString spannableString = new SpannableString(originalText);
if (TextUtils.isEmpty(originalText) || TextUtils.isEmpty(textToHighlight)) {
return spannableString;
}
String lowercaseOriginalString = originalText.toLowerCase();
String lowercaseTextToHighlight = textToHighlight.toLowerCase();
if(colorAlpha < 1){
highlightColor = ColorUtils.setAlphaComponent(highlightColor, ((int)(255*colorAlpha)));
}
//Get the previous spans and remove them
BackgroundColorSpan[] backgroundSpans = spannableString.getSpans(0, spannableString.length(), BackgroundColorSpan.class);
for (BackgroundColorSpan span: backgroundSpans) {
spannableString.removeSpan(span);
}
//Search for all occurrences of the keyword in the string
int indexOfKeyword = (ignoreCase)
? lowercaseOriginalString.indexOf(lowercaseTextToHighlight)
: originalText.indexOf(textToHighlight);
while (indexOfKeyword != -1) {
//Create a background color span on the keyword
spannableString.setSpan(new BackgroundColorSpan(highlightColor), indexOfKeyword,
indexOfKeyword + (textToHighlight.length()), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
//Get the next index of the keyword
indexOfKeyword = (ignoreCase)
? lowercaseOriginalString.indexOf(lowercaseTextToHighlight, (indexOfKeyword) + textToHighlight.length())
: originalText.indexOf(textToHighlight, (indexOfKeyword) + textToHighlight.length());
}
return spannableString;
}
https://github.com/datanapps/HighlightedTextView
<datanapps.highlightedtextview.HighLightTextView
android:id="@+id/tv2"
android:layout_below="@+id/tv1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Android is an open source and Linux-based operating system for mobile devices such as smartphones and tablet computers."
android:textColor="@color/white"
app:fontFamily="serif"
android:lineSpacingExtra="50sp"
android:layout_marginTop="20dp"
android:textSize="20sp"
android:textAlignment="viewEnd"
app:highLightColor="@color/blue"
/>
我有一个带有随机背景颜色的 TextView(实际上可以是任何颜色)。我在这个 Textview 上也有一段文本需要可读。 我认为最好的解决方案是用白色突出显示所述文本并将文本颜色设置为黑色。
我的问题是:是否可以从 XML 中突出显示 texview 中的文本?
我的布局中有以下内容:
<TextView
android:layout_width="100dp"
android:layout_height="100dp"
android:id="@+id/colorButton4"
android:layout_gravity="right|bottom"
android:background="@drawable/layout_border"
android:layout_marginRight="30dp"
android:layout_marginBottom ="30dp"
android:clickable="true"
android:onClick="onClick"
android:gravity="center"
android:textColorHighlight="@color/bgWhite"
android:textColor="@color/Black"
android:text="5431354" />
但它不会突出显示文本。
如果您查看了 TextView 的文档,您会发现 android:textColorHighlight
没有按照您的意愿执行:https://developer.android.com/reference/android/widget/TextView.html#attr_android:textColorHighlight
仅在选择文本时使用,例如在 EditText 中。您需要将TextView的背景设置为"hightlight"它。
您可能想为此使用 SpannableString,它允许字符串的各个部分在 TextView 中以不同方式呈现。
像这样:
SpannableString str = new SpannableString("Highlighted. Not highlighted.");
str.setSpan(new BackgroundColorSpan(Color.YELLOW), 0, 11, 0);
textView.setText(str);
要突出显示所有出现的特定文本,请使用此方法:
private void highlightString(String input) {
//Get the text from text view and create a spannable string
SpannableString spannableString = new SpannableString(mTextView.getText());
//Get the previous spans and remove them
BackgroundColorSpan[] backgroundSpans = spannableString.getSpans(0, spannableString.length(), BackgroundColorSpan.class);
for (BackgroundColorSpan span: backgroundSpans) {
spannableString.removeSpan(span);
}
//Search for all occurrences of the keyword in the string
int indexOfKeyword = spannableString.toString().indexOf(input);
while (indexOfKeyword > 0) {
//Create a background color span on the keyword
spannableString.setSpan(new BackgroundColorSpan(Color.YELLOW), indexOfKeyword, indexOfKeyword + input.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
//Get the next index of the keyword
indexOfKeyword = spannableString.toString().indexOf(input, indexOfKeyword + input.length());
}
//Set the final text on TextView
mTextView.setText(spannableString);}
注意:mTextView 是您要在其中突出显示文本的 TextView 对象
简单的方法
您可以使用 Spannable class 来格式化文本。
textView.setText("Hello, I am Awesome, Most Awesome"); // set text first
setHighLightedText(textView, "a"); // highlight all `a` in TextView
输出将类似于下图。
方法在这里
/**
* use this method to highlight a text in TextView
*
* @param tv TextView or Edittext or Button (or derived from TextView)
* @param textToHighlight Text to highlight
*/
public void setHighLightedText(TextView tv, String textToHighlight) {
String tvt = tv.getText().toString();
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);
}
}
}
您可以
我写了一个 Kotlin 方法,它将突出显示 String
中所有出现的所有关键字,并且 return SpannableString
.
fun main() {
textView.text = highlightKeywords(
highlightColor = ContextCompat.getColor(context, R.color.colorAccent),
message = "Hello World, and Hello to all my Hello Friends.",
keywords = listOf("Hello")
)
}
fun highlightKeywords(
highlightColor: Int,
message: String,
keywords: List<String>,
): SpannableString {
val spannableString = SpannableString(message)
keywords.forEach { keyword ->
if (!keyword.isBlank()) {
var startIndex = message.indexOf(keyword)
while (startIndex >= 0) {
spannableString.setSpan(
ForegroundColorSpan(highlightColor),
startIndex,
startIndex + keyword.length,
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
)
startIndex = message.indexOf(keyword, startIndex + keyword.length)
}
}
}
return spannableString
}
在 Android 上工作了 4 年后,我可以 有把握地说,没有 XML 之外的代码是不可能的。 如果您可以使用一些代码,那么其他人共享的解决方案将对您有所帮助,所以请阅读!
编辑:我选择了一个有效的新答案,但它需要对自定义 TextView 进行编码!
"test"
:"This is a Test"
将找不到任何内容。
这是我更新的答案,它通过传递的参数解决了这两个问题,并且还添加了 alpha,以防您想使用自定义颜色突出显示。请注意,重载的第一个方法是一个示例,用于说明如何 return 除了第一个被选中的项目之外,之前的方法做了什么。
/**
* Use this method to get the same return as the previous method
*/
public static SpannableString buildHighlightString(String originalText, String textToHighlight){
return buildHighlightString(originalText, textToHighlight, false, Color.YELLOW, 1.0F);
}
/**
* Build a spannable String for use in highlighting text colors
*
* @param originalText The original text that is being highlighted
* @param textToHighlight The text / query that determines what to highlight
* @param ignoreCase Whether or not to ignore case. If true, will ignore and "test" will have
* the same return as "TEST". If false, will return an item as highlighted
* only if it matches it case specficic.
* @param highlightColor The highlight color to use. IE {@link Color#YELLOW} || {@link Color#BLUE}
* @param colorAlpha Alpha to adjust how transparent the color is. 1.0 means it looks exactly
* as it should normally where as 0.0 means it is completely transparent and
* see-through. 0.5 means it is 50% transparent. Useful for darker colors
*/
public static SpannableString buildHighlightString(String originalText, String textToHighlight,
boolean ignoreCase, @ColorInt int highlightColor,
@FloatRange(from = 0.0, to = 1.0) float colorAlpha){
SpannableString spannableString = new SpannableString(originalText);
if (TextUtils.isEmpty(originalText) || TextUtils.isEmpty(textToHighlight)) {
return spannableString;
}
String lowercaseOriginalString = originalText.toLowerCase();
String lowercaseTextToHighlight = textToHighlight.toLowerCase();
if(colorAlpha < 1){
highlightColor = ColorUtils.setAlphaComponent(highlightColor, ((int)(255*colorAlpha)));
}
//Get the previous spans and remove them
BackgroundColorSpan[] backgroundSpans = spannableString.getSpans(0, spannableString.length(), BackgroundColorSpan.class);
for (BackgroundColorSpan span: backgroundSpans) {
spannableString.removeSpan(span);
}
//Search for all occurrences of the keyword in the string
int indexOfKeyword = (ignoreCase)
? lowercaseOriginalString.indexOf(lowercaseTextToHighlight)
: originalText.indexOf(textToHighlight);
while (indexOfKeyword != -1) {
//Create a background color span on the keyword
spannableString.setSpan(new BackgroundColorSpan(highlightColor), indexOfKeyword,
indexOfKeyword + (textToHighlight.length()), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
//Get the next index of the keyword
indexOfKeyword = (ignoreCase)
? lowercaseOriginalString.indexOf(lowercaseTextToHighlight, (indexOfKeyword) + textToHighlight.length())
: originalText.indexOf(textToHighlight, (indexOfKeyword) + textToHighlight.length());
}
return spannableString;
}
https://github.com/datanapps/HighlightedTextView
<datanapps.highlightedtextview.HighLightTextView
android:id="@+id/tv2"
android:layout_below="@+id/tv1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Android is an open source and Linux-based operating system for mobile devices such as smartphones and tablet computers."
android:textColor="@color/white"
app:fontFamily="serif"
android:lineSpacingExtra="50sp"
android:layout_marginTop="20dp"
android:textSize="20sp"
android:textAlignment="viewEnd"
app:highLightColor="@color/blue"
/>