我不知道如何让TextView上的特定文本变成粗体。
就像这样
txtResult.setText(id+" "+name);
我希望输出结果像这样:
1111 neil
id
和 name
是我从数据库中检索到的变量值。我想使 id
变为粗体,但只有 id
而不影响到 name
,我不知道该怎么做。
我不知道如何让TextView上的特定文本变成粗体。
就像这样
txtResult.setText(id+" "+name);
我希望输出结果像这样:
1111 neil
id
和 name
是我从数据库中检索到的变量值。我想使 id
变为粗体,但只有 id
而不影响到 name
,我不知道该怎么做。
只需在HTML中构建您的字符串并设置:
String sourceString = "<b>" + id + "</b> " + name;
mytextview.setText(Html.fromHtml(sourceString));
Html.fromHtml()
已被弃用。 - Someone Somewhere虽然你可以使用Html.fromHtml(),但你也可以使用一种更本地化的方法,即SpannableStringBuilder,这个帖子可能会有所帮助。
SpannableStringBuilder str = new SpannableStringBuilder("Your awesome text");
str.setSpan(new android.text.style.StyleSpan(android.graphics.Typeface.BOLD), INT_START, INT_END, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
TextView tv=new TextView(context);
tv.setText(str);
首先,您无需担心使用Raghav Sood的回答中的性能缓慢的代码。
其次,在使用Kotlin时,您无需编写w3bshark的答案提供的扩展函数。
最后,您只需要使用Google的Kotlin android-ktx库(请参见此处以查找更多信息并了解如何将其包含在您的项目中):
// Suppose id = 1111 and name = neil (just what you want).
val s = SpannableStringBuilder()
.bold { append(id) }
.append(name)
txtResult.setText(s)
输出:1111 neil
更新:
因为我认为它可能对其他人有帮助,同时也可以展示您可以在这里做到什么程度,这里有更多的用例。
当你需要显示一段文本,并且其中一些部分是蓝色和斜体时:
val myCustomizedString = SpannableStringBuilder()
.color(blueColor, { append("A blue text ") })
.append("showing that ")
.italic{ append("it is painless") }
当你需要同时显示粗体和斜体的文本时:
bold { italic { append("Bold and italic") } }
简而言之,bold
、append
、color
和italic
是用于SpannableStringBuilder
的扩展函数。您可以在官方文档中看到其他扩展函数,从中您可以想到其他可能性。
我认为选定的答案没有提供令人满意的结果。我编写了自己的函数,它接受两个字符串;完整文本和要加粗的文本部分。
它返回一个SpannableStringBuilder,其中将'text'中的'textToBold'加粗。
我发现能够使子字符串加粗而不用将其包装在标签中很有用。
/**
* Makes a substring of a string bold.
* @param text Full text
* @param textToBold Text you want to make bold
* @return String with bold substring
*/
public static SpannableStringBuilder makeSectionOfTextBold(String text, String textToBold){
SpannableStringBuilder builder=new SpannableStringBuilder();
if(textToBold.length() > 0 && !textToBold.trim().equals("")){
//for counting start/end indexes
String testText = text.toLowerCase(Locale.US);
String testTextToBold = textToBold.toLowerCase(Locale.US);
int startingIndex = testText.indexOf(testTextToBold);
int endingIndex = startingIndex + testTextToBold.length();
//for counting start/end indexes
if(startingIndex < 0 || endingIndex <0){
return builder.append(text);
}
else if(startingIndex >= 0 && endingIndex >=0){
builder.append(text);
builder.setSpan(new StyleSpan(Typeface.BOLD), startingIndex, endingIndex, 0);
}
}else{
return builder.append(text);
}
return builder;
}
正如wtsang02所说,使用HTML会增加不必要的开销。建议使用原生解决方案。如果您不需要修改字符串,只需使用SpannableString,而不是SpannableStringBuilder。
String boldText = "id";
String normalText = "name";
SpannableString str = new SpannableString(boldText + normalText);
str.setSpan(new StyleSpan(Typeface.BOLD), 0, boldText.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
textView.setText(str);
如果您想要使用来自XML的字符串,可以像这样操作:
strings.xml(“CDATA”部分很重要,否则它将无法正常工作)
<string name="test">
<![CDATA[
<b>bold!</b> normal
]]>
</string>
布局文件
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity">
<TextView
android:id="@+id/textView" android:layout_width="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="center" />
</FrameLayout>
代码
textView.text = HtmlCompat.fromHtml(getString(R.string.test), HtmlCompat.FROM_HTML_MODE_LEGACY)
<string name="test"><b>加粗文本</b>其他文本</string>
。如果我写成 <![CDATA[
则无效。 - sara很简单,只需像这样关闭指定的文本,例如<b>"你的文本在这里:"</b>
<string name="headquarters">"<b>"Headquarters:"</b>" Mooresville, North Carolina, U.S.</string>
结果: 总部:美国北卡罗来纳州穆尔斯维尔。
如果您正在使用Kotlin,则使用 core-ktx
更易于执行此操作,因为它提供了一个针对特定领域的语言(DSL) 来实现此目的:
val string: SpannedString = buildSpannedString {
bold {
append("foo")
}
append("bar")
}
它提供的更多选项包括:
append("Hello There")
bold {
append("bold")
italic {
append("bold and italic")
underline {
append("then some text with underline")
}
}
}
最后,您只需:textView.text = string
根据 @mladj0ni 的回答,我成功运行了下面的代码。问题是当你使用 String.format 时,它会剥离 html 标记,因此您必须在 strings.xml 中转义括号符号:
strings.xml:
<string name="welcome_messages">你好,%1$s!您有 <b>%2$d 条新消息</b>。</string>
code.java:
String unspanned = String.format(Locale.US, "%s%s", getResources().getString(R.string. welcome_messages), 99);
Spanned spanned;
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N) {
spanned = Html.fromHtml(unspanned, Html.FROM_HTML_MODE_LEGACY);
} else {
spanned = Html.fromHtml(unspanned);
}
textView.setText(spanned);
它比SpannableStringBuilder更简单。至于性能,如果您只显示一个字符串,那么用户不会注意到解析它需要额外的一毫秒。
请查看此处的文档。
如果您想将多个文本加粗,这里有一个更好的解决方案。我已经改进了Eitan的代码。感谢Eitan。
public static SpannableStringBuilder makeSectionOfTextBold(String text, String... textToBold) {
SpannableStringBuilder builder = new SpannableStringBuilder(text);
for (String textItem :
textToBold) {
if (textItem.length() > 0 && !textItem.trim().equals("")) {
//for counting start/end indexes
String testText = text.toLowerCase(Locale.US);
String testTextToBold = textItem.toLowerCase(Locale.US);
int startingIndex = testText.indexOf(testTextToBold);
int endingIndex = startingIndex + testTextToBold.length();
if (startingIndex >= 0 && endingIndex >= 0) {
builder.setSpan(new StyleSpan(Typeface.BOLD), startingIndex, endingIndex, 0);
}
}
}
return builder;
}