2012-08-09 14 views
6

Nella mia app utilizzo il metodo Html.fromHtml (stringa) .toString per rimuovere alcuni tag <p> che vengono ricevuti quando analizzo alcuni JSON.HTML.fromHtml aggiunge spazio alla fine del testo?

Se lascio i tag <p>, il testo si adatta perfettamente allo sfondo (lo sfondo è un layout relativo con wrap_content sia in altezza che in larghezza.) Tuttavia, se utilizzo da Html per rimuovere i tag <p>, improvvisamente c'è un enorme spazio sotto il testo, che credo sia il metodo fromHtml che aggiunge spazio alla fine?

Qualche idea?

EDIT:

Qui ci sono le immagini: http://imgur.com/a/zIZNo

Quello con <p> tag è quello che pretende molto usare fromHtml, ovviamente! :)

MODIFICA 2: La soluzione è stata trovata, vedere la mia risposta di seguito. Grazie ad Andro Selva per avermi aiutato dicendomi dello /n nascosto che è stato aggiunto!

+0

qualsiasi schermata relativa alla differenza sarà utile Immagino che –

+0

aggiunto screenshot! –

risposta

8

soluzione è stata trovata:

fromHtml restituisce il tipo spanning. Così ho assegnato ciò che veniva restituito a una variabile, convertito in una stringa e quindi utilizzato il metodo .trim().

Ha rimosso tutto lo spazio bianco alla fine.

+0

Funziona perfettamente. –

+0

funziona come un fascino. Thx amico. trim() è la soluzione :)) – alicanbatur

+3

Questo elimina il riempimento extra, ma rimuove anche tutti i tipi di formattazione (ad esempio grassetto, corsivo ..) che potrebbero esserci nello span. Quindi, perché preoccuparsi anche con l'html ?? – Jakob

5

Sì, quello che hai pensato è davvero corretto. Aggiunge spazio al fondo. Ma prima lascia che ti spieghi come funziona.

È necessario esaminare la classe HTML per vedere come funziona.

Per semplificare, è così che funziona: ogni volta che la classe Html esamina un tag <p>, ciò che fa è semplicemente aggiungere due "\ n" caratteri alla fine.

In questo caso lo spazio vuoto che si vede in basso è in realtà a causa dei due n aggiunti alla fine del paragaraph.

E ho aggiunto il metodo effettivo della classe Html che è responsabile di questa azione,

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"); 

    } 
} 

Se si desidera ignorare questa azione, è necessario sostituire la classe Html stessa, che è un po 'complicato e non può essere completato qui.

EDIT

ecco il link alla classe Html,

Html class

+0

Grazie per avermi informato del '/ n' che è stato aggiunto. Comunque ho trovato la mia soluzione, scriverò la risposta qui sotto. –

2

Se si sta tentando di utilizzarlo in un oggetto o cercando di inserirsi in un luogo specifico, provare a utilizzare <a> tag al posto di un <p>, <p> aggiunge restituisce carrozze, alla fine, un scrive nessuno, ma bisogna ricordare per scrivere lo , <b>, e mantenere lo stile

0

La spiegazione di @Andro Selva è corretta e non c'è molto da fare al riguardo. Frustrante, le cose si fanno meglio per API 24 e successivamente con l'inserimento di bandiere nella chiamata

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

e ho il sospetto il FROM_HTML_SEPARATOR_LINE_BREAK_PARAGRAPH bandiera ridurrà il doppio "\ n \ n" della terminazione paragrafo standard che del singolo "\ n" di una interruzione di riga

Data la cronologia delle versioni Android disponibili ~ Non posso permettermi di scrivere esclusivamente software per Android API 24+! Quindi ... Ho trovato una soluzione kludge con l'inclusione di 2 tag personalizzati extra.

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

sia invocare la classe RelativeSizeSpan attraverso questo metodo

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); 
        } 
       } 
      } 

che è chiamato dal TagHandler personalizzato fornito al Html.fromHtml metodo, vale a dire:

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; 
... 
      } 

     } 

Per utilizzare, ho impostato il dimensione del testo dell'oggetto Textview su 1. Cioè, 1 pixel! Quindi ho impostato la dimensione del testo vero richiesta richiesta nella variabile mDefaultTextSize. Ho tutte le funzionalità Html all'interno di un htmlTextView che si estende TextView come:

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 

}

che include il metodo pubblico

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; 
    } 

Una semplice ((htmlTextView)tv).setDefaultTextMetrics(null, 30); chiamata imposta il mio htmlTextView di utilizzare il mio carattere di serie come valore predefinito con una dimensione del testo di 30.

Quindi quando I g ive in questo esempio per utilizzare in 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> 

mia tag personalizzato <box> consente solo di sottolineare lo sfondo del testo. Vedere l'immagine allegata, che mostra uno dei risultati utilizzando il tag <default> con la dimensione TextView testo impostato a 1 e il tag <default> invocando un RelevantSizeSpan di un fattore 30, e uno 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> 

non usando <default> tag ma l'impostazione la dimensione del testo TextView invece di 30. Nel primo caso la nuova linea extra è ancora lì ma è alta solo 1 pixel!

NB I tag non contengono alcun punto reale. Sono appena lasciati manufatti da altri test.

Risultati: Entrambi gli esempi di seguito presentano 2 newline tra paragrafi ma, in quello a sinistra, una di queste righe è alta solo 1 pixel. Lascerò al lettore per capire come ridurlo a zero, ma non usare una dimensione del testo di 0

Problemi correlati