Las respuestas proporcionadas aquí son correctas, pero no se pueden llamar en un bucle porque el StyleSpan
objeto es un solo tramo contiguo (no es un estilo que se pueda aplicar a varios tramos). Llamar setSpan
varias veces con la misma negrita StyleSpan
crearía un intervalo en negrita y simplemente lo movería en el intervalo principal.
En mi caso (mostrar resultados de búsqueda), necesitaba que todas las instancias de todas las palabras clave de búsqueda aparecieran en negrita. Esto es lo que hice:
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;
}
Tenga en cuenta que el código anterior no es lo suficientemente inteligente como para omitir el doble negrita si una palabra clave es una subcadena de la otra. Por ejemplo, si busca "Fish fi" dentro de "Fishes in the fisty Sea" , el "pez" aparecerá en negrita una vez y luego la parte "fi" . Lo bueno es que, si bien es ineficiente y un poco indeseable, no tendrá un inconveniente visual, ya que el resultado que se muestra todavía se verá como
Pescado es en la fi Mar pocilga