Как сделать часть текста Полужирным шрифтом в android во время выполнения?
A ListView
в моем приложении имеет много строковых элементов, таких как name
, experience
, date of joining
и т.д. Я просто хочу сделать name
полужирным. Все строковые элементы будут в одном TextView
.
мой XML:
<ImageView
android:id="@+id/logo"
android:layout_width="55dp"
android:layout_height="55dp"
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp"
android:layout_marginTop="15dp" >
</ImageView>
<TextView
android:id="@+id/label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="@id/logo"
android:padding="5dp"
android:textSize="12dp" >
</TextView>
Мой код для установки TextView элемента ListView:
holder.text.setText(name + "\n" + expirience + " " + dateOfJoininf);
Ответы
Ответ 1
Скажите, что у вас есть TextView
, называемый etx
. Затем вы использовали бы следующий код:
final SpannableStringBuilder sb = new SpannableStringBuilder("HELLOO");
final StyleSpan bss = new StyleSpan(android.graphics.Typeface.BOLD); // Span to make text bold
final StyleSpan iss = new StyleSpan(android.graphics.Typeface.ITALIC); //Span to make text italic
sb.setSpan(bss, 0, 4, Spannable.SPAN_INCLUSIVE_INCLUSIVE); // make first 4 characters Bold
sb.setSpan(iss, 4, 6, Spannable.SPAN_INCLUSIVE_INCLUSIVE); // make last 2 characters Italic
etx.setText(sb);
Ответ 2
На основе ответа Imran Rana здесь приведен общий метод многократного использования, если вам нужно применить StyleSpan
к нескольким TextView
s с поддержкой нескольких языков (где индексы являются переменными):
void setTextWithSpan(TextView textView, String text, String spanText, StyleSpan style) {
SpannableStringBuilder sb = new SpannableStringBuilder(text);
int start = text.indexOf(spanText);
int end = start + spanText.length();
sb.setSpan(style, start, end, Spannable.SPAN_INCLUSIVE_INCLUSIVE);
textView.setText(sb);
}
Используйте его в Activity
так:
@Override
protected void onCreate(Bundle savedInstanceState) {
// ...
StyleSpan boldStyle = new StyleSpan(Typeface.BOLD);
setTextWithSpan((TextView) findViewById(R.id.welcome_text),
getString(R.string.welcome_text),
getString(R.string.welcome_text_bold),
boldStyle);
// ...
}
strings.xml
<string name="welcome_text">Welcome to CompanyName</string>
<string name="welcome_text_bold">CompanyName</string>
Результат:
Добро пожаловать в CompanyName
Ответ 3
Ответы, приведенные здесь, являются правильными, но не могут быть вызваны в цикле, потому что объект StyleSpan
представляет собой единый непрерывный диапазон (не стиль, который может применяться к нескольким промежуткам). Вызов setSpan
несколько раз с тем же жирным шрифтом StyleSpan
создаст один жирный диапазон и просто переместит его в родительском диапазоне.
В моем случае (с отображением результатов поиска) мне нужно было сделать все экземпляры всех ключевых слов поиска полужирным. Это то, что я сделал:
private static SpannableStringBuilder emboldenKeywords(final String text,
final String[] searchKeywords) {
// searching in the lower case text to make sure we catch all cases
final String loweredMasterText = text.toLowerCase(Locale.ENGLISH);
final SpannableStringBuilder span = new SpannableStringBuilder(text);
// for each keyword
for (final String keyword : searchKeywords) {
// lower the keyword to catch both lower and upper case chars
final String loweredKeyword = keyword.toLowerCase(Locale.ENGLISH);
// start at the beginning of the master text
int offset = 0;
int start;
final int len = keyword.length(); // let calculate this outside the 'while'
while ((start = loweredMasterText.indexOf(loweredKeyword, offset)) >= 0) {
// make it bold
span.setSpan(new StyleSpan(Typeface.BOLD), start, start+len, SPAN_INCLUSIVE_INCLUSIVE);
// move your offset pointer
offset = start + len;
}
}
// put it in your TextView and smoke it!
return span;
}
Имейте в виду, что приведенный выше код недостаточно умен, чтобы пропускать двойное смещение, если одно ключевое слово является подстрокой другого. Например, если вы ищете "Fish fi" внутри "Fishes in the fisty Sea", он сделает "рыбу" полужирным, а затем "fi". Хорошо, что, хотя он неэффективен и немного нежелателен, он не будет иметь визуального недостатка, так как ваш отображаемый результат будет по-прежнему выглядеть как
Рыба es в fi стиле Море
Ответ 4
если вы не знаете точно длину текста перед текстовой частью, которую хотите сделать полужирным шрифтом, или даже не знаете, сколько текста выделено полужирным шрифтом, вы можете легко использовать теги HTML, такие как следующее:
yourTextView.setText(Html.fromHtml("text before " + "<font><b>" + "text to be Bold" + "</b></font>" + " text after"));
Ответ 5
Расширение ответа frieder на случай поддержки и диакритическую нечувствительность.
public static String stripDiacritics(String s) {
s = Normalizer.normalize(s, Normalizer.Form.NFD);
s = s.replaceAll("[\\p{InCombiningDiacriticalMarks}]", "");
return s;
}
public static void setTextWithSpan(TextView textView, String text, String spanText, StyleSpan style, boolean caseDiacriticsInsensitive) {
SpannableStringBuilder sb = new SpannableStringBuilder(text);
int start;
if (caseDiacriticsInsensitive) {
start = stripDiacritics(text).toLowerCase(Locale.US).indexOf(stripDiacritics(spanText).toLowerCase(Locale.US));
} else {
start = text.indexOf(spanText);
}
int end = start + spanText.length();
if (start > -1)
sb.setSpan(style, start, end, Spannable.SPAN_INCLUSIVE_INCLUSIVE);
textView.setText(sb);
}
Ответ 6
Вы можете сделать это, используя функцию расширения Kotlin и buildSpannedString
из core-ktx
holder.textView.text = buildSpannedString {
bold { append("$name\n") }
append("$experience $dateOfJoining")
}
Ответ 7
Я рекомендую использовать файл strings.xml с CDATA
<string name="mystring"><![CDATA[ <b>Hello</b> <i>World</i> ]]></string>
Затем в файле java:
TextView myTextView = (TextView) this.findViewById(R.id.myTextView);
myTextView.setText(Html.fromHtml( getResources().getString(R.string.mystring) ));