多个字体到单个自定义 TextView

Posted

技术标签:

【中文标题】多个字体到单个自定义 TextView【英文标题】:Multiple fonts to a single custom TextView 【发布时间】:2018-07-27 05:28:01 【问题描述】:

我们如何在单个自定义TextView 中使用不同样式的 Roboto(或任何其他)字体(Roboto-Regular、Roboto-Thin、Roboto-Bold 等)。

here 描述了以编程方式执行此操作的方法之一。但是如果我们想使用 XML 改变样式,如何实现这一点。

这可以使用这样的自定义属性来完成吗?

<com.project.abc.customviews.XYZTextView
        android:layout_
        android:layout_
        android:text="Welcome"
        app:type="thin" />

我不想为每种类型制作不同的 java 文件。 here 描述了另一种方法,但这在内存方面存在问题。正在寻找一个好的解决方案。

【问题讨论】:

您必须以编程方式进行。在xml中你只能声明一次。 【参考方案1】:

我是这样实现的:

    创建了一个自定义的 TextView

    public class CaptainTextView extends TextView 
    private HashMap<String, Typeface> mTypefaces;
    
    public CaptainTextView(Context context) 
        super(context);
    
    
    public CaptainTextView(Context context, @Nullable AttributeSet attrs) 
        super(context, attrs);
    super(context, attrs, defStyleAttr);
    if (mTypefaces == null) 
        mTypefaces = new HashMap<>();
    
    
    if (this.isInEditMode()) 
        return;
    
    
    final TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.CaptainTextView);
    if (array != null) 
        final String typefaceAssetPath = array.getString(
            R.styleable.CaptainTextView_customTypeface);
    
        if (typefaceAssetPath != null) 
            Typeface typeface;
    
            if (mTypefaces.containsKey(typefaceAssetPath)) 
                typeface = mTypefaces.get(typefaceAssetPath);
             else 
                AssetManager assets = context.getAssets();
                typeface = Typeface.createFromAsset(assets, typefaceAssetPath);
                mTypefaces.put(typefaceAssetPath, typeface);
            
    
            setTypeface(typeface);
        
        array.recycle();
    
    
    
    public CaptainTextView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) 
        super(context, attrs, defStyleAttr);
        if (mTypefaces == null) 
            mTypefaces = new HashMap<>();
        
    
        if (this.isInEditMode()) 
            return;
        
    
        final TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.CaptainTextView);
        if (array != null) 
            final String typefaceAssetPath = array.getString(
                R.styleable.CaptainTextView_customTypeface);
    
            if (typefaceAssetPath != null) 
                Typeface typeface;
    
                if (mTypefaces.containsKey(typefaceAssetPath)) 
                    typeface = mTypefaces.get(typefaceAssetPath);
                 else 
                    AssetManager assets = context.getAssets();
                    typeface = Typeface.createFromAsset(assets, typefaceAssetPath);
                    mTypefaces.put(typefaceAssetPath, typeface);
                
    
                setTypeface(typeface);
            
            array.recycle();
        
    
    
    

    声明了一个自定义属性

    <resources>
    <declare-styleable name="CaptainTextView">
        <attr name="customTypeface" format="string" />
    </declare-styleable>
    </resources>
    

    在 XML 中使用

    <com.project.captain.customviews.CaptainTextView
        android:layout_
        android:layout_
        android:text="Welcome"
        android:textSize="16sp"
        android:textStyle="bold"
        app:customTypeface="fonts/Roboto-Thin.ttf" />
    

瞧!

【讨论】:

以上是关于多个字体到单个自定义 TextView的主要内容,如果未能解决你的问题,请参考以下文章

自定义TextView带有各类.ttf字体的TextView

在使用xml的android TextView中使用自定义字体

简单实现自定义Android TextView字体

android:无法设置自定义字体

RuntimeException:无法制作本机字体或自定义 TextView 加载字体的内存泄漏

自定义 TextView 字体不适用于从 java android 设置文本