web-dev-qa-db-fra.com

Comment définir la police d'objet pouvant être étendue avec une police personnalisée

J'ai un objet extensible dont je veux définir la police par une police personnalisée que j'ai chargée auparavant.

Typeface tf = Typeface.createFromAsset(getAssets(), "fonts/font_Name.ttf");
Spannable span1 = /*Spannable Item*/;

/// I want to set span1 to have tf font face???
/// Here where I want help.

MODIFIER :
Mon problème est que je veux définir deux polices personnalisées différentes pour la vue texte, donc je travaille avec le Spannable

60
mohamedghonemi

Il s'agit d'une réponse tardive, mais elle aidera d'autres personnes à résoudre le problème.

Utilisez le code suivant: (J'utilise la police Bangla et tamoule)

  TextView txt = (TextView) findViewById(R.id.custom_fonts);  
        txt.setTextSize(30);
        Typeface font = Typeface.createFromAsset(getAssets(), "Akshar.ttf");
        Typeface font2 = Typeface.createFromAsset(getAssets(), "bangla.ttf");   
        SpannableStringBuilder SS = new SpannableStringBuilder("আমারநல்வரவு");
        SS.setSpan (new CustomTypefaceSpan("", font2), 0, 4,Spanned.SPAN_EXCLUSIVE_INCLUSIVE);
        SS.setSpan (new CustomTypefaceSpan("", font), 4, 11,Spanned.SPAN_EXCLUSIVE_INCLUSIVE);
        txt.setText(SS);

Le résultat est:

enter image description here


Classe CustomTypefaceSpan:

package my.app;
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);
}
}

Référence

187
Imran Rana

Créez une classe CustomTypefaceSpan:

import Android.graphics.Paint;
import Android.graphics.Typeface;
import Android.text.TextPaint;
import Android.text.style.MetricAffectingSpan;

public class CustomTypefaceSpan extends MetricAffectingSpan {

    private final Typeface typeface;

    public CustomTypefaceSpan(Typeface typeface) {
        this.typeface = typeface;
    }

    @Override
    public void updateDrawState(TextPaint ds) {
        applyCustomTypeFace(ds, typeface);
    }

    @Override
    public void updateMeasureState(TextPaint Paint) {
        applyCustomTypeFace(Paint, typeface);
    }

    private static void applyCustomTypeFace(Paint paint, Typeface tf) {
        Paint.setTypeface(tf);
    }
}

Utilisez-le de la même manière que le framework Android s'étend sur les classes:

    TextView textView = (TextView) findViewById(R.id.custom_fonts);
    Typeface font = Typeface.createFromAsset(getAssets(), "Akshar.ttf");
    Typeface font2 = Typeface.createFromAsset(getAssets(), "bangla.ttf");
    SpannableStringBuilder spannableStringBuilder = new SpannableStringBuilder("আমারநல்வரவு");
    spannableStringBuilder.setSpan (new CustomTypefaceSpan(font2), 0, 4,Spanned.SPAN_EXCLUSIVE_INCLUSIVE);
    spannableStringBuilder.setSpan (new CustomTypefaceSpan(font), 4, 11,Spanned.SPAN_EXCLUSIVE_INCLUSIVE);
    textView.setText(spannableStringBuilder);

Cette réponse est basée sur la réponse d'Imran Rana mais n'étend pas TypefaceSpan et désactive ensuite sa fonctionnalité. CustomTypefaceSpan étend MetricAffectingSpan directement.

Cette réponse partage un défaut avec la réponse d'Imran Rana. La travée n'est pas morcelée. C'est-à-dire si vous faites cela (kotlin):

    val parcel = Parcel.obtain()
    TextUtils.writeToParcel(spannableStringBuilder, parcel, 0)
    parcel.setDataPosition(0)
    val sequence = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(parcel)
    parcel.recycle()

Tous les objets CustomTypefaceSpan définis sur spannableStringBuilder ne seront pas triés et non triés.

14
alexbirkett

Nous n'avons pas besoin d'utiliser CustomTypefaceSpan. Voici la solution.

/**
* setCustomFontTypeSpan
* @param context
* @param source
* @param startIndex
* @param endIndex
* @param font
* @return
*/
public static SpannableString setCustomFontTypeSpan(Context context, String 
source, int startIndex, int endIndex, int font) {
      final SpannableString spannableString = new SpannableString(source);
      Typeface typeface = ResourcesCompat.getFont(context, font);
      spannableString.setSpan(new StyleSpan(typeface.getStyle()), 
      startIndex,endIndex,Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
return spannableString;
}

String source = "Hello world";
SpannableString string = setCustomFontTypeSpan(context, source, 6, 
source.length(), R.font.open_sans_bold);
textView.setText(string);
11
Himanshu

Si vous utilisez Roboto, vous pouvez définir un autre TypefaceSpan dans le constructeur

TypefaceSpan typefaceSpan = new TypefaceSpan("sans-serif-medium");

textView.setSpan(typefaceSpan, indexStart, textLength, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
10
Renan Nery

Essayez de définir d'abord votre Spannable sur votre TextView puis essayez d'attribuer la police de caractères à votre TextView avec myTextView.setTypeface(tf);

1
serkanozel