91

以前にロードしたカスタムフォントでフォントを設定したい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を使用していることです

4

10 に答える 10

231

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

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

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

結果は次のとおりです。

ここに画像の説明を入力してください


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

参照

于 2012-05-24T16:03:17.670 に答える
28

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

この回答はImranRanaの回答に基づいていますが、拡張TypefaceSpanしてその機能を無効にすることはありません。CustomTypefaceSpan直接伸びMetricAffectingSpanます。

この回答は、ImranRanaの回答と欠陥を共有しています。スパンはパーセルされていません。つまり、これを行う場合(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およびアンマーシャリングされません。

于 2017-09-22T08:13:37.977 に答える
20

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

/**
* 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);
于 2018-07-17T09:50:32.390 に答える
16

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

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

textView.setSpan(typefaceSpan, indexStart, textLength, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
于 2016-03-04T19:52:20.100 に答える
7

android KTXを使用している場合buildSpannable{...}

これをお勧めします。

inline fun SpannableStringBuilder.font(typeface: Typeface? = null, builderAction: SpannableStringBuilder.() -> Unit) =
    inSpans(StyleSpan(typeface?.style ?: Typeface.DEFAULT.style), builderAction = builderAction)

使用法

binding.title.text = buildSpannedString {
    color(getColor(R.color.main_mint)) {
        font(getFont(R.font.notosans_medium)) {
            append("colored and typefaced")
        }
    }
}
于 2021-01-07T03:44:22.653 に答える
5

kotlinでは次のようになります。

最初のステップ、このクラスを作成します

class CustomTypefaceSpan(family: String?, private val newType: Typeface) :
  TypefaceSpan(family) {
  override fun updateDrawState(ds: TextPaint) {
      applyCustomTypeFace(ds, newType)
  }

  override fun updateMeasureState(paint: TextPaint) {
      applyCustomTypeFace(paint, newType)
  }

  companion object {
      private fun applyCustomTypeFace(paint: Paint, tf: Typeface) {
          val oldStyle: Int
          val old = paint.typeface
          oldStyle = old?.style ?: 0
          val fake = oldStyle and tf.style.inv()
          if (fake and Typeface.BOLD != 0) {
              paint.isFakeBoldText = true
          }
          if (fake and Typeface.ITALIC != 0) {
              paint.textSkewX = -0.25f
          }
          paint.typeface = tf
      }
  }

}

2番目のステップ

    val prefixText = SpannableString("I read and accept ")
    val prefixTextLen = prefixText.length

    prefixText.setSpan(
        CustomTypefaceSpan("", ResourcesCompat.getFont(context, R.font.gotham_bold)!!),
        0,
        prefixTextLen,
        0
    )
于 2020-02-08T13:20:49.713 に答える
5

> =API28に対するより新しく簡単な回答

val myTypeface = Typeface.create(ResourcesCompat.getFont(context, R.font.acme), Typeface.NORMAL)
val string = SpannableString("Text with typeface span.")
string.setSpan(TypefaceSpan(myTypeface), 10, 18, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
string.setSpan(TypefaceSpan("monospace"), 19, 22, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)

textView.text = string
于 2020-08-20T21:47:33.630 に答える
1

を最初に設定してSpannableから、TypefaceをwithTextViewに割り当ててみてください。TextViewmyTextView.setTypeface(tf)

于 2011-07-07T14:48:10.660 に答える
1

同じことをしたかったのですが、TypefaceSpanを使用する必要があることがわかりました。問題は、書体をとるコンストラクターがAPIレベル28でのみ追加されることです。したがって、私が見つけた回避策は、次のことを行うことです。

val spannable = SpannableString("My String")
spannable.setSpan(object : TypefaceSpan(null) {
    override fun updateDrawState(ds: TextPaint) {
        ds.typeface = Typeface.create(ResourcesCompat.getFont(context, R.font.my_font), Typeface.NORMAL) // To change according to your need
    }
}, start, end, Spannable.SPAN_INCLUSIVE_EXCLUSIVE) // To change according to your need
myTextView.setText(spannable)
于 2021-02-13T18:47:57.120 に答える
-1

これは、strが完全な文字列であり、boldStringが太字にする必要がある部分である例です。

public static SpannableString getTextStyleSpan(String str, String boldString) {

        SpannableString formated = new SpannableString(str);

        int start1 = str.indexOf(boldString);
        int end1 = start1 + colorString1.length();

        formated.setSpan(new android.text.style.StyleSpan(android.graphics.Typeface.BOLD), start1, end1, Spannable.SPAN_INCLUSIVE_INCLUSIVE);
        return formated;
    }
于 2016-04-28T15:22:42.287 に答える