2012-01-09 20 views
7

Tengo los siguientes datos de entrada en Cadena: "Hola # este # es # muestra # texto".Eliminar caracteres de la secuencia de caracteres intercambiable

Establece el color de fondo para todos los elementos entre # caracteres. Esto es lo que obtuve hasta ahora:

public static CharSequence colorBackground(CharSequence text) { 

    Pattern pattern = Pattern.compile("#(.*?)#"); 

    Spannable spannable = new SpannableString(text); 
    if(pattern != null) 
    { 
     Matcher matcher = pattern.matcher(text); 
     while(matcher.find()) 
     { 
      int start = matcher.start(); 
      int end = matcher.end(); 
      CharacterStyle span = new BackgroundColorSpan(0xFF404040); 
      spannable.setSpan(span, start, end, 0); 
     } 
    } 
    return spannable; 
} 

Establecer el color de fondo funciona, pero los caracteres de marcador de posición # también tienen un estilo. ¿Cómo eliminarlos antes de devolver el resultado, porque el método ReplaceAll no existe para CharSequence?

Utilizo esta función para aplicar estilo a las filas de TextView en ListView. Se siente un poco más lento en el emulador después de agregar esta función de estilo. Tal vez debería abordarlo de alguna otra manera, por ej. usar una vista de texto personalizada con función de dibujo personalizado?

Respuesta

12

Esto sonaba como algo divertido de tratar de descubrir.

La clave era SpannableStringBuilder. Con SpannableString el texto en sí mismo es inmutable, pero con SpannableStringBuilder tanto el texto como el marcado se pueden cambiar. Con esto en mente he modificado el fragmento un poco para hacer lo que quiera:

public static CharSequence colorBackground(CharSequence text) { 

    Pattern pattern = Pattern.compile("#(.*?)#"); 

    SpannableStringBuilder ssb = new SpannableStringBuilder(text); 

    if(pattern != null) 
    { 
     Matcher matcher = pattern.matcher(text); 
     int matchesSoFar = 0; 
     while(matcher.find()) 
     { 
      int start = matcher.start() - (matchesSoFar * 2); 
      int end = matcher.end() - (matchesSoFar * 2); 
      CharacterStyle span = new BackgroundColorSpan(0xFF404040); 
      ssb.setSpan(span, start + 1, end - 1, 0); 
      ssb.delete(start, start + 1); 
      ssb.delete(end - 2, end -1); 
      matchesSoFar++; 
     } 
    } 
    return ssb; 
} 

no tengo mucha experiencia con Spannables en general, y no sé si la forma en que he ido acerca de la eliminación el "#" es el mejor método, pero parece funcionar.

+0

Gracias por su tiempo, los Spannables son un poco confusos de trabajar al principio. Al menos funciona más rápido que desde HTML. – joshas

0

¿Cómo eliminarlos antes de devolver el resultado, porque el método ReplaceAll no existe para CharSequence?

Se podría adoptar el enfoque de Html.fromHtml() - construir el SpannedString, no trate de modificar en su lugar.

Cuestiones relacionadas