Наведені тут відповіді є правильними, але їх не можна викликати у циклі, оскільки 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's 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" у "Fish in the fisty Sea", це зробить "рибу" жирною один раз, а потім "fi" частину. Хороша річ полягає в тому, що, хоча він неефективний і трохи небажаний, він не матиме візуального недоліку, оскільки відображається результат все одно буде виглядати як
Риба - ес в фі StY море