¿Cómo puedo utilizar TypefaceSpan o StyleSpan con un tipo de letra personalizado?
No he encontrado una manera de hacer esto. ¿Es posible?
Aceptado
Bueno, no pude descubrir cómo hacerlo con las clases disponibles, así que amplié el método TypefaceSpan
por mi cuenta y ahora me funciona. Aquí esta lo que hice:
package de.myproject.text.style;
import android.graphics.Paint;
import android.graphics.Typeface;
import android.text.TextPaint;
import android.text.style.TypefaceSpan;
public class CustomTypefaceSpan extends TypefaceSpan {
private final Typeface newType;
public CustomTypefaceSpan(String family, Typeface type) {
super(family);
newType = type;
}
@Override
public void updateDrawState(TextPaint ds) {
applyCustomTypeFace(ds, newType);
}
@Override
public void updateMeasureState(TextPaint paint) {
applyCustomTypeFace(paint, newType);
}
private static void applyCustomTypeFace(Paint paint, Typeface tf) {
int oldStyle;
Typeface old = paint.getTypeface();
if (old == null) {
oldStyle = 0;
} else {
oldStyle = old.getStyle();
}
int fake = oldStyle & ~tf.getStyle();
if ((fake & Typeface.BOLD) != 0) {
paint.setFakeBoldText(true);
}
if ((fake & Typeface.ITALIC) != 0) {
paint.setTextSkewX(-0.25f);
}
paint.setTypeface(tf);
}
}
Si bien notme tiene esencialmente la idea correcta, la solución dada es un poco complicada ya que "familia" se vuelve redundante. También es ligeramente incorrecto porque TypefaceSpan es uno de los tramos especiales que Android conoce y espera cierto comportamiento con respecto a la interfaz ParcelableSpan (que la subclase de notme no implementa correctamente ni es posible implementar).
Una solución más sencilla y precisa sería:
public class CustomTypefaceSpan extends MetricAffectingSpan
{
private final Typeface typeface;
public CustomTypefaceSpan(final Typeface typeface)
{
this.typeface = typeface;
}
@Override
public void updateDrawState(final TextPaint drawState)
{
apply(drawState);
}
@Override
public void updateMeasureState(final TextPaint paint)
{
apply(paint);
}
private void apply(final Paint paint)
{
final Typeface oldTypeface = paint.getTypeface();
final int oldStyle = oldTypeface != null ? oldTypeface.getStyle() : 0;
final int fakeStyle = oldStyle & ~typeface.getStyle();
if ((fakeStyle & Typeface.BOLD) != 0)
{
paint.setFakeBoldText(true);
}
if ((fakeStyle & Typeface.ITALIC) != 0)
{
paint.setTextSkewX(-0.25f);
}
paint.setTypeface(typeface);
}
}