programacion - ¿Cómo hacer parte del texto Bold en Android en tiempo de ejecución?
manual de programacion android pdf (6)
Un ListView
en mi aplicación tiene muchos elementos de cadena como el name
, la experience
, la date of joining
, etc. Solo quiero poner el name
negrita. Todos los elementos de cadena estarán en un solo TextView
.
mi 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>
Mi código para configurar TextView del elemento ListView:
holder.text.setText(name + "/n" + expirience + " " + dateOfJoininf);
Extendiendo la respuesta de frieder a la insensibilidad al caso de apoyo y diacríticos.
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);
}
Las respuestas proporcionadas aquí son correctas, pero no se pueden llamar en un bucle porque el objeto StyleSpan
es un tramo contiguo único (no es un estilo que se puede aplicar a tramos múltiples). Llamar a setSpan
varias veces con el mismo StyleSpan
negrita crearía un tramo audaz y simplemente lo movería en el lapso principal.
En mi caso (visualización de 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 enlace si una palabra clave es una subcadena de la otra. Por ejemplo, si busca "Fish fi" dentro de "Fishes in the Fisty Sea" hará que el "pez" sea 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 aún se verá como
Peces es en el mar fi del
Recomiendo usar el archivo strings.xml con CDATA
<string name="mystring"><![CDATA[ <b>Hello</b> <i>World</i> ]]></string>
Luego en el archivo java:
TextView myTextView = (TextView) this.findViewById(R.id.myTextView);
myTextView.setText(Html.fromHtml( getResources().getString(R.string.mystring) ));
Según la respuesta de Imran Rana, este es un método genérico y reutilizable si necesita aplicar StyleSpan
s a varios TextView
s, con soporte para múltiples idiomas (donde los índices son variables):
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);
}
Úselo en una Activity
como esta:
@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>
Resultado:
Bienvenido a CompanyName
Supongamos que tiene un TextView
llamado etx
. Entonces usarías el siguiente código:
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);
si no sabe exactamente la longitud del texto antes de la porción de texto que desea convertir en negrita, o incluso si no sabe que la longitud del texto es negrita, puede usar fácilmente etiquetas HTML como las siguientes:
yourTextView.setText(Html.fromHtml("text before " + "<font><b>" + "text to be Bold" + "</b></font>" + " text after"));