2012-08-09 16 views
6

En mi aplicación, uso el método Html.fromHtml (cadena) .toString para eliminar algunas etiquetas <p> que se reciben cuando analizo un JSON.HTML.fromHtml agrega espacio al final del texto?

Si dejo las <p> etiquetas, el texto se ajusta al fondo a la perfección (el fondo es un diseño en relación con wrap_content tanto en altura como en anchura.) Sin embargo, si uso fromHtml para eliminar los <p> etiquetas, suddenely hay una espacio enorme debajo del texto, que creo que es el método fromHtml que agrega espacio al final?

¿Alguna idea?

EDIT:

Aquí son capturas: http://imgur.com/a/zIZNo

El uno con <p> etiquetas es el que imposible utilizar fromHtml, obviamente! :)

EDIT 2: se ha encontrado una solución, consulte mi respuesta a continuación. ¡Gracias a Andro Selva por ayudarme contándome sobre el oculto /n que se estaba agregando!

+0

cualquier captura de pantalla relacionada con la diferencia será útil Supongo que –

+0

capturas de pantalla adicionales! –

Respuesta

8

Solución:

fromHtml devuelve el tipo abarcado. Así que asigné lo que se devolvía a una variable, lo convertí en una cadena y luego usé el método .trim() en él.

Se eliminó todo el espacio en blanco al final.

+0

Funciona a la perfección. –

+0

funciona como un encanto. Thx amigo. trim() es la solución :)) – alicanbatur

+3

Eso elimina el relleno adicional, pero también elimina todo tipo de formateo (por ejemplo, negrita, cursiva ...) puede haber en el tramo .. Entonces, ¿por qué molestarse con el html? ?? – Jakob

5

Sí, lo que pensaste es realmente correcto. Agrega espacio al fondo. Pero antes de eso déjame explicarte cómo funciona esto.

Tienes que mirar la clase HTML para ver cómo funciona.

Para ser simple, así es como funciona: siempre que su clase Html mire una etiqueta <p>, lo que hace es simplemente agregar dos caracteres "\ n" al final.

En este caso, el espacio vacío que se ve en la parte inferior es en realidad debido a los dos \ n añadidos al final del parárafo.

Y he añadido el método real de la clase HTML que es responsable de esta acción,

private static void handleP(SpannableStringBuilder text) { 
    int len = text.length(); 

    if (len >= 1 && text.charAt(len - 1) == '\n') { 
     if (len >= 2 && text.charAt(len - 2) == '\n') { 
      return; 
     } 
     text.append("\n"); 
     return; 
    } 

    if (len != 0) { 

     text.append("\n\n"); 

    } 
} 

Si desea anular esta acción, usted tiene que anular la propia clase HTML que es un poco complicado y no puede ser completado aquí. Se encontró

EDITAR

aquí está el enlace a la clase Html,

Html class

+0

Gracias por informarme sobre el '/ n' que se estaba agregando. Sin embargo, encontré mi propia solución, escribiré la respuesta a continuación. –

2

Si usted está tratando de usarlo en un objeto o tratar de encajar en un lugar específico, trate de usar <a> etiqueta en lugar de una <p>, <p> añade devuelve carruajes al final, una escribe ninguna, pero hay que recordar para escribir el \n usted mismo con <b>, y usted puede mantener el estilo

0

La explicación de @Andro Selva es correcta y no hay mucho que hacer al respecto. Frustrante, las cosas mejoran para la API de 24 y más tarde con la inclusión de banderas en la llamada

Spanned fromHtml (String source, 
       int flags, 
       Html.ImageGetter imageGetter, 
       Html.TagHandler tagHandler); 

y sospecho que la FROM_HTML_SEPARATOR_LINE_BREAK_PARAGRAPH bandera reducirá el doble "\ n \ n" de la terminación párrafo estándar a ese del único "\ n" de un salto de línea

Dado el historial de versiones de Android ~ no puedo permitirme escribir software para Android API 24+ exclusivamente. Entonces ... Encontré una solución de kludge con la inclusión de 2 etiquetas personalizadas adicionales.

1. <scale factor="x.xx">... </scale> 
2. <default>... </default> 

tanto invocar la clase RelativeSizeSpan través de este método

private void ProcessRelativeSizeTag(float scalefactor, boolean opening, Editable output) { 
       int len = output.length(); 
       if (opening) { 
        System.out.println("scalefactor open: " + scalefactor); 
        output.setSpan(new RelativeSizeSpan(scalefactor), len, len, 
          Spannable.SPAN_MARK_MARK); 
       } else { 
        Object obj = getLast(output, RelativeSizeSpan.class); 
        int where = output.getSpanStart(obj); 
        scalefactor = ((RelativeSizeSpan)obj).getSizeChange(); 
        output.removeSpan(obj); 
        System.out.println("scalefactor close: " + scalefactor); 
        if (where != len) { 
         output.setSpan(new RelativeSizeSpan(scalefactor), where, len, 
           Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); 
        } 
       } 
      } 

que se llama desde el TagHandler personalizada suministrada al Html.fromHtml método, a saber:

private static class CustomTagHandler implements Html.TagHandler { 

    private void ProcessRelativeSizeTag(float scalefactor, boolean opening, Editable output) { 
      int len = output.length(); 
      if (opening) { 
       //mSizeStack.push(scalefactor); 
       System.out.println("scalefactor open: " + scalefactor); 
       output.setSpan(new RelativeSizeSpan(scalefactor), len, len, 
         Spannable.SPAN_MARK_MARK); 
      } else { 
       Object obj = getLast(output, RelativeSizeSpan.class); 
       int where = output.getSpanStart(obj); 
       scalefactor = ((RelativeSizeSpan)obj).getSizeChange(); 

       output.removeSpan(obj); 

       //scalefactor = (float)mSizeStack.pop(); 
       System.out.println("scalefactor close: " + scalefactor); 
       if (where != len) { 
        output.setSpan(new RelativeSizeSpan(scalefactor), where, len, 
          Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); 
       } 
      } 
     } 
... 
     final HashMap<String, String> mAttributes = new HashMap<>(); 

     @Override 
     public void handleTag(boolean opening, String tag, Editable output, XMLReader xmlReader) { 
      String Attr; 
      processAttributes(xmlReader); 
      if ("default".equalsIgnoreCase(tag)) { 
       ProcessRelativeSizeTag(mDefaultTextSize, opening, output); 
       return; 
      } 

      if ("scale".equalsIgnoreCase(tag)) { 
       Attr = mAttributes.get("factor"); 
       if (Attr != null && !Attr.isEmpty()) { 
        float factor = parseFloat(Attr); 
        if (factor > 0) 
         ProcessRelativeSizeTag(factor, opening, output); 
       } 
       return; 
... 
      } 

     } 

Para utilizar, me puse la el tamaño del texto del objeto Textview es 1. ¡Es decir, 1 píxel! A continuación, establezco el tamaño de texto verdadero requerido requerido en la variable mDefaultTextSize. Tengo toda la funcionalidad de HTML dentro de un htmlTextView que se extiende TextView como:

public class htmlTextView extends AppCompatTextView { 
    static Typeface mLogo; 
    static Typeface mGAMZ; 
    static Typeface mBrush; 
    static Typeface mStandard; 
    int GS_PAINTFLAGS = FILTER_BITMAP_FLAG | ANTI_ALIAS_FLAG | SUBPIXEL_TEXT_FLAG | HINTING_ON; 
    static float mDefaultTextSize; 
    static Typeface mDefaultTypeface; 
etc 

}

que incluye el método público

public void setDefaultTextMetrics(String face, float defaultTextSize) { 
     mDefaultTypeface = mStandard; 
     if (face != null) { 
      if ("gamz".equalsIgnoreCase(face)) { 
       mDefaultTypeface = mGAMZ; 
      } else { 
       if ("brush".equalsIgnoreCase(face)) { 
        mDefaultTypeface = mBrush; 
       } 
      } 
     } 
     setTypeface(mDefaultTypeface); 
     setTextSize(1); 
     mDefaultTextSize = defaultTextSize; 
    } 

Un simple ((htmlTextView)tv).setDefaultTextMetrics(null, 30); llamada me pone el htmlTextView usar mi tipo de letra estándar como predeterminado con un tamaño de texto de 30.

Luego cuando g ive que este ejemplo para utilizar en fromHtml:

<string name="htmlqwert"> 
<![CDATA[ 
     <p><default><scale factor="1.5"><box> qwertQWERT </box></scale></default></p> 
     <p><default><scale factor="1.5"><box> qwertQWERT </box></scale></default></p> 
     <p><default><scale factor="1.5"><box> qwertQWERT </box></scale></default></p> 
     <p><default><scale factor="1.5"><box> qwertQWERT </box></scale></default></p> 
]]> 
</string> 

mi etiqueta personalizada <box> simplemente me permite poner de relieve el fondo del texto. Ver la imagen adjunta, que muestra un resultado utilizando la etiqueta <default> con el tamaño TextView texto que figura a 1 y el <default> etiqueta de la invocación de una RelevantSizeSpan por un factor de 30, y una con:

<string name="htmlqwert"> 
    <![CDATA[ 
      <p><scale factor="1.5"><box> qwertQWERT </box></scale></p> 
      <p><scale factor="1.5"><box>qwertQWERT</box></scale></p> 
      <p><scale factor="1.5"><box>qwertQWERT</box></scale></p> 
      <p><scale factor="1.5"><box>qwertQWERT</box></scale></p> 
    ]]> 
    </string> 

utilizar ninguna etiqueta <default> pero el establecimiento el tamaño de texto TextView a 30 en su lugar. En el primer caso, la nueva línea aún está allí, pero tiene solo 1 píxel de alto.

NB No hay ningún punto real para las etiquetas <scale factor="1.5">...</scale>. Solo quedan artefactos de otras pruebas.

Resultados: Ambos ejemplos a continuación tienen 2 nuevas líneas entre párrafos pero, en el de la izquierda, una de esas líneas tiene solo 1 píxel de alto. Dejaré que el lector descubra cómo reducirlo a cero, pero no use un tamaño de texto de 0

Cuestiones relacionadas