¿Es posible tener varios estilos dentro de un TextView?

¿Es posible establecer varios estilos para diferentes partes de texto dentro de un TextView?

Por ejemplo, estoy fijando el texto como sigue:

tv.setText(line1 + "\n" + line2 + "\n" + word1 + "\t" + word2 + "\t" + word3); 

¿Es posible tener un estilo diferente para cada elemento de texto? Por ejemplo, línea1 negrita, palabra1 cursiva, etc.

Las Tareas comunes de la guía para desarrolladores y cómo hacerlas en Android incluye Selección, resaltado o estilización de partes de texto :

 // Get our EditText object. EditText vw = (EditText)findViewById(R.id.text); // Set the EditText's text. vw.setText("Italic, highlighted, bold."); // If this were just a TextView, we could do: // vw.setText("Italic, highlighted, bold.", TextView.BufferType.SPANNABLE); // to force it to use Spannable storage so styles can be attached. // Or we could specify that in the XML. // Get the EditText's internal text storage Spannable str = vw.getText(); // Create our span sections, and assign a format to each. str.setSpan(new StyleSpan(android.graphics.Typeface.ITALIC), 0, 7, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); str.setSpan(new BackgroundColorSpan(0xFFFFFF00), 8, 19, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); str.setSpan(new StyleSpan(android.graphics.Typeface.BOLD), 21, str.length() - 1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); 

Pero eso utiliza números de posición explícitos dentro del texto. ¿Hay una manera más limpia de hacer esto?

En caso, cualquier persona se está preguntando cómo hacer esto, aquí está una manera: (¡Gracias a la marca otra vez!)

 mBox = new TextView(context); mBox.setText(Html.fromHtml("<b>" + title + "</b>" + "<br />" + "<small>" + description + "</small>" + "<br />" + "<small>" + DateAdded + "</small>")); 

Para obtener una lista no oficial de etiquetas compatibles con este método, consulte este enlace o esta pregunta: ¿Qué etiquetas HTML son compatibles con Android TextView?

Pruebe Html.fromHtml() , y marque su texto con negrita y cursiva etiquetas HTML, por ejemplo:

 Spanned text = Html.fromHtml("This mixes <b>bold</b> and <i>italic</i> stuff"); textView.setText(text); 

Un poco fuera de tema, pero encontré esto muy útil para no ser mencionado aquí.

¿Qué pasa si nos gustaría leer el texto Html desde el recurso string.xml y por lo tanto hacerlo más fácil de localizar. CDATA hacen esto posible:

 <string name="my_text"> <![CDATA[ <b>Autor:</b> Mr Nice Guy<br/> <b>Contact:</b> [email protected]<br/> <i>Copyright © 2011-2012 Intergalactic Spacebar Confederation </i> ]]> </string> 

Desde nuestro código Java ahora podríamos utilizarlo así:

 TextView tv = (TextView) findViewById(R.id.myTextView); tv.setText(Html.fromHtml(getString(R.string.my_text))); 

No esperaba que esto funcionara. Pero lo hizo.

Espero que sea útil para algunos de ustedes!

Si no te apetece usar html, podrías crear un styles.xml y usarlo así:

 TextView tv = (TextView) findViewById(R.id.textview); SpannableString text = new SpannableString(myString); text.setSpan(new TextAppearanceSpan(getContext(), R.style.myStyle), 0, 5, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); text.setSpan(new TextAppearanceSpan(getContext(), R.style.myNextStyle), 6, 10, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); tv.setText(text, TextView.BufferType.SPANNABLE); 

Una respuesta muy tarde aquí, pero la lista de etiquetas compatibles está aquí: http://developer.android.com/guide/faq/commontasks.html#selectingtext

También muestra que Html.fromHtml no es realmente necesario

Es más ligero utilizar un SpannableString vez del marcado del html. Me ayuda a ver ejemplos visuales, así que aquí hay una respuesta suplementaria.

Introduzca aquí la descripción de la imagen

Este es un único TextView .

 // set the text SpannableString s1 = new SpannableString("bold\n"); SpannableString s2 = new SpannableString("italic\n"); SpannableString s3 = new SpannableString("foreground color\n"); SpannableString s4 = new SpannableString("background color\n"); SpannableString s5 = new SpannableString("underline\n"); SpannableString s6 = new SpannableString("strikethrough\n"); SpannableString s7 = new SpannableString("bigger\n"); SpannableString s8 = new SpannableString("smaller\n"); SpannableString s9 = new SpannableString("font\n"); SpannableString s10 = new SpannableString("URL span\n"); SpannableString s11 = new SpannableString("clickable span\n"); SpannableString s12 = new SpannableString("overlapping spans\n"); // set the style int flag = Spanned.SPAN_EXCLUSIVE_EXCLUSIVE; s1.setSpan(new StyleSpan(Typeface.BOLD), 0, s1.length(), flag); s2.setSpan(new StyleSpan(Typeface.ITALIC), 0, s2.length(), flag); s3.setSpan(new ForegroundColorSpan(Color.RED), 0, s3.length(), flag); s4.setSpan(new BackgroundColorSpan(Color.YELLOW), 0, s4.length(), flag); s5.setSpan(new UnderlineSpan(), 0, s5.length(), flag); s6.setSpan(new StrikethroughSpan(), 0, s6.length(), flag); s7.setSpan(new RelativeSizeSpan(2), 0, s7.length(), flag); s8.setSpan(new RelativeSizeSpan(0.5f), 0, s8.length(), flag); s9.setSpan(new TypefaceSpan("monospace"), 0, s9.length(), flag); s10.setSpan(new URLSpan("https://developer.android.com"), 0, s10.length(), flag); s11.setSpan(new ClickableSpan() { @Override public void onClick(View widget) { Toast.makeText(getApplicationContext(), "Span clicked", Toast.LENGTH_SHORT).show(); } }, 0, s11.length(), flag); s12.setSpan(new ForegroundColorSpan(Color.RED), 0, 11, flag); s12.setSpan(new BackgroundColorSpan(Color.YELLOW), 4, s12.length(), flag); s12.setSpan(new UnderlineSpan(), 4, 11, flag); // build the string SpannableStringBuilder builder = new SpannableStringBuilder(); builder.append(s1); builder.append(s2); builder.append(s3); builder.append(s4); builder.append(s5); builder.append(s6); builder.append(s7); builder.append(s8); builder.append(s9); builder.append(s10); builder.append(s11); builder.append(s12); // set the text view with the styled text textView.setText(builder); // enables clicking on spans for clickable span and url span textView.setMovementMethod(LinkMovementMethod.getInstance()); 

Estudio adicional

  • Explicar el significado de las banderas Span como SPAN_EXCLUSIVE_EXCLUSIVE
  • Extensión de Spanned, SpannedString, Spannable, SpannableString y CharSequence de Android
  • Tipos de tramos

Este ejemplo fue inspirado originalmente de aquí .

Yo estaba corriendo en el mismo problema. Podría usar fromHtml, pero ahora soy Android, no web, así que decidí probarlo. Tengo que localizar esto sin embargo así que le di un tiro usando el concepto de reemplazo de cadena. Establecer el estilo en el TextView para ser el estilo principal, a continuación, sólo el formato de los otros peices.

Espero que esto ayude a otros que buscan hacer la misma cosa – no sé porqué esto no es más fácil en el marco.

Mis cuerdas tienen este aspecto:

 <string name="my_text">{0} You will need a {1} to complete this assembly</string> <string name="text_sub0">1:</string> <string name="text_sub1">screwdriver, hammer, and measuring tape</string> 

Aquí están los estilos:

 <style name="MainStyle"> <item name="android:textSize">@dimen/regular_text</item> <item name="android:textColor">@color/regular_text</item> </style> <style name="style0"> <item name="android:textSize">@dimen/paragraph_bullet</item> <item name="android:textColor">@color/standout_text</item> <item name="android:textStyle">bold</item> </style> <style name="style1"> <item name="android:textColor">@color/standout_light_text</item> <item name="android:textStyle">italic</item> </style> 

Aquí está mi código que llama a mi método formatStyles:

 SpannableString formattedSpan = formatStyles(getString(R.string.my_text), getString(R.string.text_sub0), R.style.style0, getString(R.string.main_text_sub1), R.style.style1); textView.setText(formattedSpan, TextView.BufferType.SPANNABLE); 

El método de formato:

 private SpannableString formatStyles(String value, String sub0, int style0, String sub1, int style1) { String tag0 = "{0}"; int startLocation0 = value.indexOf(tag0); value = value.replace(tag0, sub0); String tag1 = "{1}"; int startLocation1 = value.indexOf(tag1); if (sub1 != null && !sub1.equals("")) { value = value.replace(tag1, sub1); } SpannableString styledText = new SpannableString(value); styledText.setSpan(new TextAppearanceSpan(getActivity(), style0), startLocation0, startLocation0 + sub0.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); if (sub1 != null && !sub1.equals("")) { styledText.setSpan(new TextAppearanceSpan(getActivity(), style1), startLocation1, startLocation1 + sub1.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); } return styledText; } 

Ahora el elemento <b> está obsoleto. <strong> representa como <b> y <em> representa como <i> .

 tv.setText(Html.fromHtml("<strong>bold</strong> and <em>italic</em> ")); 

Esto funciona bien para mi

Si desea poder agregar el texto con estilo en xml, puede crear una vista personalizada que extienda TextView y reemplace setText ():

 public class HTMLStyledTextView extends TextView { public HTMLStyledTextView(Context context) { super(context); } public HTMLStyledTextView(Context context, AttributeSet attrs) { super(context, attrs); } public HTMLStyledTextView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } @Override public void setText(CharSequence text, BufferType type) { super.setText(Html.fromHtml(text.toString()), type); } } 

Entonces, puedes usarlo de esta manera (reemplaza PACKAGE_NAME con tu nombre de paquete):

 <PACKAGE_NAME.HTMLStyledTextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="<![CDATA[ <b>Bolded Text:</b> Non-Bolded Text ]]>" /> 

Esta es una manera fácil de hacerlo usando HTMLBuilder

  myTextView.setText(new HtmlBuilder(). open(HtmlBuilder.Type.BOLD). append("Some bold text "). close(HtmlBuilder.Type.BOLD). open(HtmlBuilder.Type.ITALIC). append("Some italic text"). close(HtmlBuilder.Type.ITALIC). build() ); 

Resultado:

Algunos texto en negrita Algunos texto en cursiva

Como se indica, utilice TextView.setText(Html.fromHtml(String))

Y utilizar estas etiquetas en su cadena formateada HTML:

 <a href="..."> <b> <big> <blockquote> <br> <cite> <dfn> <div align="..."> <em> <font size="..." color="..." face="..."> <h1> <h2> <h3> <h4> <h5> <h6> <i> <img src="..."> <p> <small> <strike> <strong> <sub> <sup> <tt> <u> 

http://commonsware.com/blog/Android/2010/05/26/html-tags-supported-by-textview.html

De hecho, excepto el objeto Html, también podría usar las clases de tipo Spannable, por ejemplo, TextAppearanceSpan o TypefaceSpan y SpannableString togather. La clase Html también utiliza estos mecanismos. Pero con las clases de tipo Spannable, tienes más libertad.

Puede ser tan simple como aprovechar el método length () de String:

  1. Dividir la cadena de texto en el archivo XML de Cuerdas en tantas sub-cadenas (unas cadenas separadas desde el punto de vista de Android) como muchas que necesita diferentes estilos, por lo que podría ser como: str1, str2, str3 (como en su caso) Que cuando se unen son toda la cadena única que utiliza.

  2. A continuación, simplemente siga el método "Span", al igual que usted presentó con su código, pero en lugar de una sola cadena, combine todas las subcadenas fusionándolas en una sola, cada una con un estilo personalizado diferente.

Todavía usas los números, pero no directamente – ya no toman una forma codificada (como en tu código) ahora, pero están siendo sustituidos por los métodos combinados length () (nota dos estrellas precedentes y sufijo str. Length () en lugar del número absoluto para extuinguir el cambio):

 str.setSpan(new StyleSpan(android.graphics.Typeface.ITALIC), 0, **str.length()**, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); 

Para el primer tamaño de cadena, luego str.length () + 1, str.length () + str2.length () para el segundo tamaño de cadena, y así sucesivamente con todas las subcadenas, en lugar de por ejemplo 0,7 u 8,19 y así…

Uso de una Clase Spannable auxiliar como recursos de recursos de cadenas de Android en la parte inferior de la página web. Puedes acercarte a esto creando CharSquences y dándoles un estilo.

Pero en el ejemplo que nos dan, es sólo para negrita, cursiva, e incluso colorize el texto. Necesitaba envolver varios estilos en un CharSequence para ponerlos en un TextView . Así que a esa clase (lo CharSequenceStyles ) Acabo de agregar esta función.

 public static CharSequence applyGroup(LinkedList<CharSequence> content){ SpannableStringBuilder text = new SpannableStringBuilder(); for (CharSequence item : content) { text.append(item); } return text; } 

Y en la vista agregé esto.

  message.push(postMessageText); message.push(limitDebtAmount); message.push(pretMessageText); TextView.setText(CharSequenceStyles.applyGroup(message)); 

¡Espero que esto te ayude!

Spanny hace que SpannableString sea más fácil de usar.

 Spanny spanny = new Spanny("Underline text", new UnderlineSpan()) .append("\nRed text", new ForegroundColorSpan(Color.RED)) .append("\nPlain text"); textView.setText(spanny) 
FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.