web-dev-qa-db-ja.com

Spannableオブジェクトのフォントをカスタムフォントで設定する方法

以前に読み込んだカスタムフォントでフォントを設定するSpannableオブジェクトがあります。

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.

編集:
私の問題は、テキストビューに2つの異なるカスタムフォントを設定したいので、Spannableで作業していることです

60
mohamedghonemi

これは遅い回答ですが、他の人が問題を解決するのに役立ちます。

次のコードを使用します(私はバングラとタミル語のフォントを使用しています)

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

結果は次のとおりです。

enter image description here


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

参照

187
Imran Rana

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

Androidフレームワークがクラ​​スにまたがるのと同じ方法で使用します:

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

この回答はImran Ranaの回答に基づいていますが、TypefaceSpanを拡張し、その機能を無効にしません。 CustomTypefaceSpanMetricAffectingSpanを直接拡張します。

この回答は、Imran Ranaの回答と欠陥を共有しています。スパンは分割されていません。つまり、これを行う場合(kotlin):

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

CustomTypefaceSpanに設定されたspannableStringBuilderオブジェクトは、マーシャリングもアンマーシャリングもされません。

14
alexbirkett

CustomTypefaceSpanを使用する必要はありません。これが解決策です。

/**
* 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

Robotoを使用している場合は、コンストラクターで異なるTypefaceSpanを設定できます

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

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

最初にSpannableTextViewに設定してから、myTextView.setTypeface(tf);でTextViewにタイプフェイスを割り当ててみてください。

1
serkanozel