TextViewの特定のテキストを太字にする方法がわかりません。
こんな感じです
txtResult.setText(id+" "+name);
出力を次のようにしたい:
1111ニール
id
とname
は、データベースから値を取得した変数でありid
、太字にしたいのですが、それだけが影響を受けないid
ため、name
これを行う方法がわかりません。
TextViewの特定のテキストを太字にする方法がわかりません。
こんな感じです
txtResult.setText(id+" "+name);
出力を次のようにしたい:
1111ニール
id
とname
は、データベースから値を取得した変数でありid
、太字にしたいのですが、それだけが影響を受けないid
ため、name
これを行う方法がわかりません。
回答:
HTMLで文字列を作成して設定するだけです。
String sourceString = "<b>" + id + "</b> " + name;
mytextview.setText(Html.fromHtml(sourceString));
Html.fromHtml()
廃止されました
あなたが使用することができますがHtml.fromHtmlを()あなたは、よりネイティブなアプローチを使用することができます SpannableStringBuilderを、このポストは helfulかもしれません。
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の回答にある遅いパフォーマンスコードの使用について心配する必要はありません。
2番目:Kotlinを使用する場合、w3bsharkの回答で提供される拡張関数を作成する必要はありません。
Finnaly:必要なのは、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ニール
更新:
それは他の誰かを助けることができると思うだけでなく、あなたがここまで行くことができる範囲がより多くのユースケースであることを示すのに役立つと思います。
いくつかの部分が青色で斜体のテキストを表示する必要がある場合:
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
。あなたは他の可能性を考えることができる場所から、公式のドキュメントで別の拡張関数を見ることができます。
選んだ答えは満足のいく結果にはならないと思いました。2つの文字列を取る独自の関数を作成しました。太字にしたいテキスト全体とテキストの一部。
'text'の 'textToBold'を太字にしたSpannableStringBuilderを返します。
タグで囲むことなく部分文字列を太字にする機能は便利です。
/**
* 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を使用するとオーバーヘッドが高くなります。ネイティブソリューションを使用するだけです。文字列を変更する必要がない場合は、SpannableStringBuilderではなくSpannableStringを使用してください。
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>text bold</b> other text</string>
ます。私が書いた場合は機能しません<![CDATA[
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
複数のテキストを太字にしたい場合は、これがより良い解決策です。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;
}
@ mladj0niの答えに基づいて、私は以下のコードを機能させました。問題は、String.formatを使用すると、htmlマークアップが削除されるため、strings.xml内のブラケット記号をエスケープする必要があることです。
strings.xml:
<string name="welcome_messages">Hello, %1$s! You have <b>%2$d new messages</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よりも簡単です。パフォーマンスに関しては、1つの文字列だけを表示している場合、ユーザーはそれを解析するための余分なミリ秒に気付かないでしょう。
こちらのドキュメントをご覧ください。
このコードを使用して、テキストの一部を太字に設定できます。太字のhtmlタグの間にあるものはすべて、太字になります。
String myText = "make this <b>bold</b> and <b>this</b> too";
textView.setText(makeSpannable(myText, "<b>(.+?)</b>", "<b>", "</b>"));
public SpannableStringBuilder makeSpannable(String text, String regex, String startTag, String endTag) {
StringBuffer sb = new StringBuffer();
SpannableStringBuilder spannable = new SpannableStringBuilder();
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(text);
while (matcher.find()) {
sb.setLength(0);
String group = matcher.group();
String spanText = group.substring(startTag.length(), group.length() - endTag.length());
matcher.appendReplacement(sb, spanText);
spannable.append(sb.toString());
int start = spannable.length() - spanText.length();
spannable.setSpan(new android.text.style.StyleSpan(android.graphics.Typeface.BOLD), start, spannable.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}
sb.setLength(0);
matcher.appendTail(sb);
spannable.append(sb.toString());
return spannable;
}
リスト/リサイクラーのように文字を検索しながら、文字列の最初の文字をスパン可能にする
R viとアジャイ
以前はこのように強調表示していましたが、以下のようになりたかったです
ラヴィNDアジャイ OR ラヴィとカケス
このため、1に等しい場合に単語の長さを検索しました。メイン文字列を単語に分割し、単語の開始位置を計算してから、charで始まる単語を検索しました。
public static SpannableString colorString(int color, String text, String... wordsToColor) {
SpannableString coloredString = new SpannableString(text);
for (String word : wordsToColor) {
Log.e("tokentoken", "-wrd len-" + word.length());
if (word.length() !=1) {
int startColorIndex = text.toLowerCase().indexOf(word.toLowerCase());
int endColorIndex = startColorIndex + word.length();
try {
coloredString.setSpan(new ForegroundColorSpan(color), startColorIndex, endColorIndex,
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
} catch (Exception e) {
e.getMessage();
}
} else {
int start = 0;
for (String token : text.split("[\u00A0 \n]")) {
if (token.length() > 0) {
start = text.indexOf(token, start);
// Log.e("tokentoken", "-token-" + token + " --start--" + start);
char x = token.toLowerCase().charAt(0);
char w = word.toLowerCase().charAt(0);
// Log.e("tokentoken", "-w-" + w + " --x--" + x);
if (x == w) {
// int startColorIndex = text.toLowerCase().indexOf(word.toLowerCase());
int endColorIndex = start + word.length();
try {
coloredString.setSpan(new ForegroundColorSpan(color), start, endColorIndex,
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
} catch (Exception e) {
e.getMessage();
}
}
}
}
}
}
return coloredString;
}
既存の回答に満足できなかったため、より最新のソリューションを提供するためにここに来ました。翻訳されたテキストで機能し、を使用することによるパフォーマンスへの影響がないものが必要でしたHtml.fromHtml()
。Kotlinを使用している場合は、テキストの複数の部分を簡単に太字に設定できる拡張関数を次に示します。これはMarkdownと同じように機能し、必要に応じて、他のMarkdownタグをサポートするように拡張できます。
val yourString = "**This** is your **string**.".makePartialTextsBold()
val anotherString = getString(R.string.something).makePartialTextsBold()
/**
* This function requires that the parts of the string that need
* to be bolded are wrapped in ** and ** tags
*/
fun String.makePartialTextsBold(): SpannableStringBuilder {
var copy = this
return SpannableStringBuilder().apply {
var setSpan = true
var next: String
do {
setSpan = !setSpan
next = if (length == 0) copy.substringBefore("**", "") else copy.substringBefore("**")
val start = length
append(next)
if (setSpan) {
setSpan(StyleSpan(Typeface.BOLD), start, length,
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
}
copy = copy.removePrefix(next).removePrefix("**")
} while (copy.isNotEmpty())
}
}
wtsang02( "")が非推奨になったため、回答がそれを処理する最良の方法です。ここでは、文のサイズに関係なく、最初の単語を動的に太字にする際に問題が発生している人のために、少し強調します。
最初に、最初の単語を取得するメソッドを作成します。
private String getFirstWord(String input){
for(int i = 0; i < input.length(); i++){
if(input.charAt(i) == ' '){
return input.substring(0, i);
}
}
return input;
}
ここで、次のような長い文字列があるとします。
String sentence = "friendsAwesomeName@gmail.com want's to be your friend!"
そして、あなたはあなたの文章をyourAwesomeName@gmail.comのようにしたいのです!次のように、firstWordを取得してその長さを取得し、firstWordを太字にするだけです。
String myFirstWord = getFirstWord(sentence);
int start = 0; // bold will start at index 0
int end = myFirstWord.length(); // and will finish at whatever the length of your first word
次のように、wtsang02の手順に従います。
SpannableStringBuilder fancySentence = new SpannableStringBuilder(sentence);
fancySentence.setSpan(new android.text.style.StyleSpan(Typeface.BOLD), start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
textView.setText(fancySentence);
以上です!これで、長文/短文から任意のサイズの単語を太字にすることができるはずです。それが誰かを助けることを願って、幸せなコーディング:)
これは私がこれに使用するKotlin拡張関数です
/**
* Sets the specified Typeface Style on the first instance of the specified substring(s)
* @param one or more [Pair] of [String] and [Typeface] style (e.g. BOLD, ITALIC, etc.)
*/
fun TextView.setSubstringTypeface(vararg textsToStyle: Pair<String, Int>) {
val spannableString = SpannableString(this.text)
for (textToStyle in textsToStyle) {
val startIndex = this.text.toString().indexOf(textToStyle.first)
val endIndex = startIndex + textToStyle.first.length
if (startIndex >= 0) {
spannableString.setSpan(
StyleSpan(textToStyle.second),
startIndex,
endIndex,
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
)
}
}
this.setText(spannableString, TextView.BufferType.SPANNABLE)
}
使用法:
text_view.text="something bold"
text_view.setSubstringTypeface(
Pair(
"something bold",
Typeface.BOLD
)
)
。
text_view.text="something bold something italic"
text_view.setSubstringTypeface(
Pair(
"something bold ",
Typeface.BOLD
),
Pair(
"something italic",
Typeface.ITALIC
)
)
ビルダーで2つの文字列を個別に追加できます。1つはspannedString、もう1つは通常の文字列です。これにより、インデックスを計算する必要がなくなります。
val instructionPress = resources?.getString(R.string.settings_press)
val okText = resources?.getString(R.string.ok)
val spannableString = SpannableString(okText)
val spannableBuilder = SpannableStringBuilder()
spannableBuilder.append(instructionPress)
spannableBuilder.append(spannableString, StyleSpan(Typeface.BOLD), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
instructionText.setText(spannableBuilder,TextView.BufferType.SPANNABLE)
TextViewおよびEditTextのテキストの一部を太字に設定する静的メソッドを作成しました
public static void boldPartOfText(View mView, String contentData, int startIndex, int endIndex){
if(!contentData.isEmpty() && contentData.length() > endIndex) {
final SpannableStringBuilder sb = new SpannableStringBuilder(contentData);
final StyleSpan bss = new StyleSpan(Typeface.BOLD); // Span to make text bold
final StyleSpan iss = new StyleSpan(Typeface.NORMAL); //Span to make text normal
sb.setSpan(iss, 0, startIndex, Spanned.SPAN_INCLUSIVE_INCLUSIVE);
sb.setSpan(bss, startIndex, endIndex, Spannable.SPAN_INCLUSIVE_INCLUSIVE); // make first 4 characters Bold
sb.setSpan(iss,endIndex, contentData.length()-1, Spanned.SPAN_INCLUSIVE_INCLUSIVE);
if(mView instanceof TextView)
((TextView) mView).setText(sb);
else if(mView instanceof EditText)
((EditText) mView).setText(sb);
}
}
さらにカスタマイズされたコード
/*typeFaceStyle can be passed as
Typeface.NORMAL = 0;
Typeface.BOLD = 1;
Typeface.ITALIC = 2;
Typeface.BOLD_ITALIC = 3;*/
public static void boldPartOfText(View mView, String contentData, int startIndex, int endIndex,int typeFaceStyle){
if(!contentData.isEmpty() && contentData.length() > endIndex) {
final SpannableStringBuilder sb = new SpannableStringBuilder(contentData);
final StyleSpan bss = new StyleSpan(typeFaceStyle); // Span to make text bold
final StyleSpan iss = new StyleSpan(Typeface.NORMAL); //Span to make text italic
sb.setSpan(iss, 0, startIndex, Spanned.SPAN_INCLUSIVE_INCLUSIVE);
sb.setSpan(bss, startIndex, endIndex, Spannable.SPAN_INCLUSIVE_INCLUSIVE); // make first 4 characters Bold
sb.setSpan(iss,endIndex,contentData.length()-1,Spanned.SPAN_INCLUSIVE_INCLUSIVE);
if(mView instanceof TextView)
((TextView) mView).setText(sb);
else if(mView instanceof EditText)
((EditText) mView).setText(sb);
}
}
誰かがデータバインディングを使用している場合。このようにバインディングアダプターを定義できます
@BindingAdapter("html")
fun setHtml(view: TextView, html: String) {
view.setText(HtmlCompat.fromHtml(html, HtmlCompat.FROM_HTML_MODE_LEGACY))
}
その後、TextViewで使用できます
app:html="@{@string/bold_text}"
ここでbold_textは
<string name="bold_text"><![CDATA[Part of text is <b>bold</b>]]></string>
複数の言語でローカライズを処理したい場合の方法を見つけました。これは退屈ですが機能します。これが必要だとしましょう:
英語で:
登録されている支払いはありません
スペイン語で:
干し草パゴス登録なし
あなたは3つの文字列を作成する必要があります
英語:
<string name="start_string">There are no</string>
<string name="middle_string">payments</string>
<string name="end_string">registered.</string>
<string name="string_format" translatable="false">%1$s %2$s %3$s</string>
スペイン語:
<string name="start_string">No hay</string>
<string name="middle_string">pagos</string>
<string name="end_string">registrados</string>
これでこれを行うことができます:
val startSpanPosition = getString(R.string.start_string).length
val endSpanPosition = startSpanPosition + getString(R.string.middle_string).length
val mySpannableString = SpannableStringBuilder(String.format(getString(R.string.string_format),
getString(R.string.start_string), getString(R.string.middle_string))), getString(R.string.end_string)))
mySpannableString.setSpan(StyleSpan(Typeface.BOLD), spanStartPosition, endSpanPosition, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
大文字と小文字をチェックした動的な文字列値の完全なソリューションを次に示します。
/**
* Makes a portion of String formatted in BOLD.
*
* @param completeString String from which a portion needs to be extracted and formatted.<br> eg. I am BOLD.
* @param targetStringToFormat Target String value to format. <br>eg. BOLD
* @param matchCase Match by target character case or not. If true, BOLD != bold
* @return A string with a portion formatted in BOLD. <br> I am <b>BOLD</b>.
*/
public static SpannableStringBuilder formatAStringPortionInBold(String completeString, String targetStringToFormat, boolean matchCase) {
//Null complete string return empty
if (TextUtils.isEmpty(completeString)) {
return new SpannableStringBuilder("");
}
SpannableStringBuilder str = new SpannableStringBuilder(completeString);
int start_index = 0;
//if matchCase is true, match exact string
if (matchCase) {
if (TextUtils.isEmpty(targetStringToFormat) || !completeString.contains(targetStringToFormat)) {
return str;
}
start_index = str.toString().indexOf(targetStringToFormat);
} else {
//else find in lower cases
if (TextUtils.isEmpty(targetStringToFormat) || !completeString.toLowerCase().contains(targetStringToFormat.toLowerCase())) {
return str;
}
start_index = str.toString().toLowerCase().indexOf(targetStringToFormat.toLowerCase());
}
int end_index = start_index + targetStringToFormat.length();
str.setSpan(new StyleSpan(BOLD), start_index, end_index, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
return str;
}
例えば。completeString = "私はBOLDです"
場合私*targetStringToFormat* = "bold"
と*matchCase* = true
「I am BOLD」を返します(bold!= BOLD以降)
場合II*targetStringToFormat* = "bold"
と*matchCase* = false
リターンは「私はBOLD」
応募する:
myTextView.setText(formatAStringPortionInBold("I am BOLD", "bold", false))
お役に立てば幸いです。