栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

安卓字体样式设置java.lang.NoSuchMethodErrorNo direct method <init>(Landroid/graphics/Typeface;)

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

安卓字体样式设置java.lang.NoSuchMethodErrorNo direct method <init>(Landroid/graphics/Typeface;)

正常设置字体样式如下:

SpannableString sStr = new SpannableString("这个是设置字体样式的")
sStr.setSpan(new TypefaceSpan("default"), 0, 2, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
sStr.setSpan(new TypefaceSpan("default-bold"), 2, 4, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
		sStr.setSpan(new TypefaceSpan("monospace"), 4, 6, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);

在TypefaceSpan源码中(如下)
public class TypefaceSpan extends MetricAffectingSpan implements ParcelableSpan {

    @Nullable
    private final String mFamily;

    @Nullable
    private final Typeface mTypeface;

    
    public TypefaceSpan(@Nullable String family) {
        this(family, null);
    }

    
    public TypefaceSpan(@NonNull Typeface typeface) {
        this(null, typeface);
    }

    
    public TypefaceSpan(@NonNull Parcel src) {
        mFamily = src.readString();
        mTypeface = LeakyTypefaceStorage.readTypefaceFromParcel(src);
    }

    private TypefaceSpan(@Nullable String family, @Nullable Typeface typeface) {
        mFamily = family;
        mTypeface = typeface;
    }

    @Override
    public int getSpanTypeId() {
        return getSpanTypeIdInternal();
    }

    
    @Override
    public int getSpanTypeIdInternal() {
        return TextUtils.TYPEFACE_SPAN;
    }

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(@NonNull Parcel dest, int flags) {
        writeToParcelInternal(dest, flags);
    }

    
    @Override
    public void writeToParcelInternal(@NonNull Parcel dest, int flags) {
        dest.writeString(mFamily);
        LeakyTypefaceStorage.writeTypefaceToParcel(mTypeface, dest);
    }

    
    @Nullable
    public String getFamily() {
        return mFamily;
    }

    
    @Nullable
    public Typeface getTypeface() {
        return mTypeface;
    }

    @Override
    public void updateDrawState(@NonNull TextPaint ds) {
        updateTypeface(ds);
    }

    @Override
    public void updateMeasureState(@NonNull TextPaint paint) {
        updateTypeface(paint);
    }

    private void updateTypeface(@NonNull Paint paint) {
        if (mTypeface != null) {
            paint.setTypeface(mTypeface);
        } else if (mFamily != null) {
            applyFontFamily(paint, mFamily);
        }
    }

    private void applyFontFamily(@NonNull Paint paint, @NonNull String family) {
        int style;
        Typeface old = paint.getTypeface();
        if (old == null) {
            style = Typeface.NORMAL;
        } else {
            style = old.getStyle();
        }
        final Typeface styledTypeface = Typeface.create(family, style);
        int fake = style & ~styledTypeface.getStyle();

        if ((fake & Typeface.BOLD) != 0) {
            paint.setFakeBoldText(true);
        }

        if ((fake & Typeface.ITALIC) != 0) {
            paint.setTextSkewX(-0.25f);
        }
        paint.setTypeface(styledTypeface);
    }
}

构造函数中参数可以传String family和Typeface typeface  family相当于如上的default ,default-default-bold 等 而typeface可以设置自定义下载的字体,比如
  Typeface tf = Typeface.createFromAsset(getAssets(), "test字体.ttf");
  sStr.setSpan(new TypefaceSpan("tf"), 0, 2, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
在实际开发项目中如上设置 new TypefaceSpan("tf") 字体样式时,在Android 9.0以下时会如下报错
java.lang.NoSuchMethodError
No direct method (Landroid/graphics/Typeface;)V in class Landroid/text/style/TypefaceSpan; 
or its super classes (declaration of 'android.text.style.TypefaceSpan' appears in /system/framework/framework.jar!classes2.dex)
提示framework.jar 中没有发现直接调用new TypefaceSpan("tf") 这个方法。需要自定义CustomTypefaceSpan :如下
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) {
        setCustomTypeFace(ds, newType);
    }

    @Override
    public void updateMeasureState(TextPaint paint) {
        setCustomTypeFace(paint, newType);
    }

    private void setCustomTypeFace(Paint paint, Typeface tf) {
        if (tf == null || paint == null)return;
        paint.setTypeface(tf);
    }
}

设置字体样式改成如下:
  Typeface tf = Typeface.createFromAsset(getAssets(), "test字体.ttf");
  sStr.setSpan(new CustomTypefaceSpan("tf"), 0, 2, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);

通过不同的安卓版本测试 未报如上错误日志;

 当前问题基于应用内遇到的处理方法,以上方式如果存在缺陷或者兼容性问题,欢迎一起讨论并完善。谢谢

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1028773.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号