SpannableStringBuilder para crear cadenas con múltiples fonts / tamaños de texto, etc. ¿Ejemplo?

Necesito crear una cadena colocada en un TextView que mostrará una cadena como esta:

Primera parte no negrita BOLD rest no negrita

Entonces, ¿quiero saber cómo podría usar SpannableStringBuilder para hacer esto?

Podría usar tres TextEdit para lograr esto, pero me gustaría utilizar la mejor solución.

 First Part Not Bold BOLD rest not bold 

Puedes hacer esto como @Rajesh sugerido o por esto.

 String normalBefore= "First Part Not Bold "; String normalBOLD= "BOLD "; String normalAfter= "rest not bold"; String finalString= normalBefore+normalBOLD+normalAfter; Spannable sb = new SpannableString( finalString ); sb.setSpan(new StyleSpan(android.graphics.Typeface.BOLD), finalString.indexOf(normalBOLD)+ normalBOLD.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); //bold sb.setSpan(new AbsoluteSizeSpan(intSize), finalString.indexOf(normalBOLD)+ normalBOLD.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);//resize size 

para mostrar esto en TextView

 textview.setText(sb, TextView.BufferType.SPANNABLE); 

La respuesta aceptada está bien (y la volví a subir), pero no usa SpannableStringBuilder como solicitó el remitente. Como tenía un caso en el que el Constructor tenía más sentido, aquí está el código para eso (con un uso adicional de cambiar también el color del texto si eso es útil para otros). Tenga en cuenta que también puede proporcionar la cadena inicial al constructor SpannableStringBuilder, pero la configuré aquí para usar “append” para aclarar que puede agregar mucho antes del texto “en negrita” deseado y luego simplemente registrar el inicio como se muestra. Sospecho que este es también un código más rápido que la respuesta aceptada.

 SpannableStringBuilder longDescription = new SpannableStringBuilder(); longDescription.append("First Part Not Bold "); int start = longDescription.length(); longDescription.append("BOLD"); longDescription.setSpan(new ForegroundColorSpan(0xFFCC5500), start, longDescription.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); longDescription.setSpan(new StyleSpan(android.graphics.Typeface.BOLD), start, longDescription.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); longDescription.append(" rest not bold"); 

Desde API 21 SpannableStringBuilder incluye un método simple para hacer esto. Aquí hay un ejemplo de solución:

 SpannableStringBuilder builder= new SpannableStringBuilder(); StyleSpan boldSpan = new StyleSpan(android.graphics.Typeface.BOLD); builder.append("First Part Not Bold ") .append("BOLD ", boldSpan, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE) .append("rest not bold"); 

Dado que es una buena posibilidad que no sea compatible con API 21 solo puede duplicar el código de ese método:

 public SpannableStringBuilder append(CharSequence text, Object what, int flags) { int start = length(); append(text); setSpan(what, start, length(), flags); return this; } 

Use el código HTML en TextView usando la clase Html :

 Spanned styledText = Html.fromHtml("First Part Not Bold BOLD rest not bold"); textView.setText(styledText); 

Así que sé que esto se ha resuelto, e incluso como se solicitó con SpannableStringBuilder, pero en caso de que quisieras construir una cadena de forma más dinámica, pensé que pondría esto.

 // Stuff needed TextView DataTextView = (TextView)rootView.findViewById(R.id.DataView); String Fields[] = {...database column names as strings... "x","y"}; String DataString = new String(); int start,stop; // Start and Stop of formatting // Final Result SpannableStringBuilder coloredString = new SpannableStringBuilder(); SpannableString temp; // Small segment of colored string for (int i =0; i < Fields.length; i++) { if (database_result.containsKey(Fields[i])) // Be sure a field exists in the ContentValues { DataString = Fields[i]+": "; start = DataString.length(); DataString = DataString+ +database_result.getAsInteger(Fields[i])+" "; stop= DataString.length(); temp = new SpannableString(DataString); temp.setSpan(new ForegroundColorSpan(Color.WHITE),start, stop, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); coloredString.append(temp); } } DataTextView.setText(coloredString); 

database_result es un tipo ContentValues ​​que construí a partir del tipo de Cursor devuelto de la consulta SQL. El único problema que tuve con esto fue al principio solo ColorSpaning el primer segmento. Parece que necesitas declarar un nuevo ForegroundColorSpan cada vez que quieras usar uno (o cualquier otro tipo de intervalo) en un bucle.

Este código debe establecer en negrita todo lo que entra dentro de la etiqueta html bold. Y también elimina la etiqueta para que solo se muestre el contenido en el interior.

  SpannableStringBuilder sb = new SpannableStringBuilder("this is bold and this is bold too and this is bold too, again."); Pattern p = Pattern.compile(".*?", Pattern.CASE_INSENSITIVE); boolean stop = false; while (!stop) { Matcher m = p.matcher(sb.toString()); if (m.find()) { sb.setSpan(new StyleSpan(android.graphics.Typeface.BOLD), m.start(), m.end(), Spannable.SPAN_INCLUSIVE_INCLUSIVE); sb.delete(m.end()-4, m.end()); sb.delete(m.start(), m.start() + 3); } else stop = true; } 

Este código también se puede adaptar para otras tags de estilo html, como Superíndice (etiqueta sup), etc.

  SpannableStringBuilder sb = new SpannableStringBuilder("text has superscript tag"); Pattern p = Pattern.compile(".*?", Pattern.CASE_INSENSITIVE); boolean stop = false; while (!stop) { Matcher m = p.matcher(sb.toString()); if (m.find()) { sb.setSpan(new SuperscriptSpan(), m.start(), m.end(), Spannable.SPAN_INCLUSIVE_INCLUSIVE); sb.delete(m.end()-6, m.end()); sb.delete(m.start(), m.start() + 5); } else stop = true; } 

Para establecer el color, simplemente use ForegroundColorSpan con setSpan.

 sb.setSpan(new ForegroundColorSpan(Color.rgb(255, 0, 0)), m.start(), m.end(), Spannable.SPAN_INCLUSIVE_INCLUSIVE); 

Espero eso ayude.

Si está usando Kotlin, puede hacer lo siguiente usando la biblioteca android-ktx

 val s = SpannableStringBuilder() .append("First Part Not Bold ") .bold { append("BOLD") } .append("Rest not bold") 

El bold es una función de extensión en SpannableStringBuilder . Puede ver la documentación aquí para obtener una lista de operaciones que puede usar.

Otro ejemplo:

 val s = SpannableStringBuilder() .color(green, { append("Green text ") }) .append("Normal text ") .scale(0.5, { append("Text at half size " }) .backgroundColor(green, { append("Background green") }) 

Donde el green es un color RGB resuelto.

Incluso es posible anidar tramos para que termines con un DSL incorporado:

 bold { underline { italic { append("Bold and underlined") } } } 

Necesitará lo siguiente en su build.gradle nivel de módulo de aplicación para que funcione:

 repositories { google() } dependencies { implementation 'androidx.core:core-ktx:0.3' } 

También podemos usar SpannableStringBuilder con TextAppearanceSpan para lograr eso. Siga los pasos a continuación para implementar de esa manera.

  1. Crea un estilo en styles.xml .
  

¿Por qué usarás SpannableStringBuilder cuando puedes usar SpannableBuilder? ( https://gist.github.com/qtyq/90f9b4894069a8b3676c )

 SpannableString ss = SpannableBuilder.init("First Part Not Bold BOLD rest not bold") .makeBold("BOLD") .create()