Combinación de Spannable con String.format ()

Supongamos que tiene la siguiente cadena:

String s = "The cold hand reaches for the %1$s %2$s Ellesse's"; String old = "old"; String tan = "tan"; String formatted = String.format(s,old,tan); //"The cold hand reaches for the old tan Ellesse's" 

Supongamos que desea terminar con esta cadena, pero también tiene un conjunto Span determinado para cualquier palabra reemplazada por String.format .

Por ejemplo, también queremos hacer lo siguiente:

 Spannable spannable = new SpannableString(formatted); spannable.setSpan(new StrikethroughSpan(), oldStart, oldStart+old.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); spannable.setSpan(new ForegroundColorSpan(Color.BLUE), tanStart, tanStart+tan.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); 

¿Hay una forma robusta de conocer los índices de inicio de old y tan ?

Tenga en cuenta que sólo la búsqueda de 'antiguo' devuelve el 'viejo' en 'frío', por lo que no funcionará.

Lo que funciona, supongo, es buscar %[0-9]$s antemano y calcular los desplazamientos para tener en cuenta las sustituciones en String.format . Esto parece un dolor de cabeza, aunque, sospecho que podría haber un método como String.format que es más informativo sobre los detalles de su formato. Bueno, ¿verdad?

He creado una versión de String.format que trabaja con spannables. Descárguelo y úselo como en la versión normal. En su caso, usted pondría los espacios alrededor de los especificadores de formato (posiblemente utilizando strings.xml). En la salida, estarían alrededor de lo que los especificadores fueron reemplazados con.

El uso de Spannables como eso es un dolor de cabeza – esta es probablemente la manera más sencilla:

 String s = "The cold hand reaches for the %1$s %2$s Ellesse's"; String old = "<font color=\"blue\">old</font>"; String tan = "<strike>tan</strike>"; String formatted = String.format(s,old,tan); //The cold hand reaches for the <font color="blue">old</font> <strike>tan</strike> Ellesse's Spannable spannable = Html.fromHtml(formatted); 

Problema: esto no se pone en un StrikethroughSpan . Para hacer el StrikethroughSpan , pedimos prestado un TagHandler personalizado de esta pregunta .

 Spannable spannable = Html.fromHtml(text,null,new MyHtmlTagHandler()); 

MyTagHandler:

 public class MyHtmlTagHandler implements Html.TagHandler { public void handleTag(boolean opening, String tag, Editable output, XMLReader xmlReader) { if (tag.equalsIgnoreCase("strike") || tag.equals("s")) { processStrike(opening, output); } } private void processStrike(boolean opening, Editable output) { int len = output.length(); if (opening) { output.setSpan(new StrikethroughSpan(), len, len, Spannable.SPAN_MARK_MARK); } else { Object obj = getLast(output, StrikethroughSpan.class); int where = output.getSpanStart(obj); output.removeSpan(obj); if (where != len) { output.setSpan(new StrikethroughSpan(), where, len, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); } } } private Object getLast(Editable text, Class kind) { Object[] objs = text.getSpans(0, text.length(), kind); if (objs.length == 0) { return null; } else { for (int i = objs.length; i > 0; i--) { if (text.getSpanFlags(objs[i - 1]) == Spannable.SPAN_MARK_MARK) { return objs[i - 1]; } } return null; } } } 
  • Cómo romper el texto de estilo en las páginas en Android?
  • El texto se ensucia con ImageSpan en EditText
  • Establecer arrastrar audiencia en SpannableString
  • Reemplace los caracteres con Image en string y luego seleccione Textview
  • Cambiar altura de línea / línea en EditText en un nivel de carácter
  • ¿Cómo alinear el texto tanto a la izquierda como a la derecha de una línea TextView?
  • Incorpore la línea que envuelve al usar bulletspan
  • Android Development: Cómo reemplazar parte de un EditText con un Spannable
  • ¿Por qué mi texto no aparece con estilo cuando se utiliza SpannableStringBuilder?
  • Android TextView formato de palabras múltiples
  • Ajuste de la alineación del texto mediante SpannableString
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.