我有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.
编辑:
我的问题是我想为文本视图设置两种不同的自定义字体,所以我正在使用Spannable
答案 0 :(得分:181)
这是一个迟到的答案,但会帮助其他人解决问题。
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);
结果是:
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);
}
}
答案 1 :(得分:12)
创建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
,然后禁用其功能。 CustomTypefaceSpan
直接延长MetricAffectingSpan
。
这个答案与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
个对象都不会被编组和解组。
答案 2 :(得分:9)
如果您使用的是Roboto,则可以在构造函数
中设置不同的TypefaceSpanTypefaceSpan typefaceSpan = new TypefaceSpan("sans-serif-medium");
textView.setSpan(typefaceSpan, indexStart, textLength, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
答案 3 :(得分:9)
我们不需要使用CustomTypefaceSpan。这是解决方案。
{{1}}
答案 4 :(得分:4)
如果您使用的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")
}
}
}
答案 5 :(得分:2)
在科特林将是:
第一步,创建此类
filterTuples :: [(Int, Int)] -> [(Int,Int)]
filterTuples [] = []
filterTuples (x:xs) = x:filterTuples(concat ((fst temp) : [filter (\z -> fst z /= del) (snd temp)]))
where del = fst (head (snd temp))
temp = break (\y -> (snd y == fst x)) xs
第二步,
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
}
}
}
答案 6 :(得分:2)
> = API 28的更新,更简单的答案
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
答案 7 :(得分:1)
首先尝试将Spannable
设置为TextView
,然后尝试使用TextView
将myTextView.setTypeface(tf)
分配给{{1}};
答案 8 :(得分:1)
我想做同样的事情,但我发现我需要使用 TypefaceSpan。问题是采用 Typeface 的构造函数仅在 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)
答案 9 :(得分:-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;
}