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
cualquier captura de pantalla relacionada con la diferencia será útil Supongo que –
capturas de pantalla adicionales! –