You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android自定义主题覆盖fontFamily后如何获取主题默认字体?

Android自定义View读取主题fontFamily配置实现方案

直接通过当前Context的主题对象读取系统原生android:fontFamily属性即可,不需要声明自定义styleable,天然和全局App主题配置对齐,自动实现无配置时回退系统默认字体:

核心实现逻辑

  1. 用当前View绑定的Context的Theme实例,读取android.R.attr.fontFamily属性对应的字体配置
  2. 读取到非空值直接使用,未读取到则回退系统默认字体
  3. 用完及时回收TypedArray避免内存泄漏

Kotlin实现示例

import androidx.core.content.res.TypedArrayCompat

class CustomFontView @JvmOverloads constructor(
    context: Context,
    attrs: AttributeSet? = null,
    defStyleAttr: Int = 0
) : View(context, attrs, defStyleAttr) {

    // 主题配置的字体,为空则用系统默认
    private val themeFont: Typeface?

    init {
        val typedArray = context.theme.obtainStyledAttributes(intArrayOf(android.R.attr.fontFamily))
        try {
            // 兼容API14+的读取方式,不需要高版本系统权限
            themeFont = TypedArrayCompat.getFont(typedArray, 0)
        } finally {
            typedArray.recycle()
        }

        // 绘制文本时直接使用即可,示例:
        val textPaint = Paint(Paint.ANTI_ALIAS_FLAG).apply {
            typeface = themeFont ?: Typeface.DEFAULT
            textSize = 52f
        }
    }

    // 其余自定义绘制逻辑...
}

Java实现示例

import androidx.core.content.res.TypedArrayCompat;

public class CustomFontView extends View {
    private Typeface themeFont;

    public CustomFontView(Context context) {
        super(context);
        init(context);
    }

    public CustomFontView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(context);
    }

    public CustomFontView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context);
    }

    private void init(Context context) {
        TypedArray typedArray = context.getTheme().obtainStyledAttributes(
                new int[]{android.R.attr.fontFamily}
        );
        try {
            themeFont = TypedArrayCompat.getFont(typedArray, 0);
        } finally {
            typedArray.recycle();
        }

        // 使用示例
        Paint textPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        textPaint.setTypeface(themeFont != null ? themeFont : Typeface.DEFAULT);
        textPaint.setTextSize(52f);
    }

    // 其余自定义绘制逻辑...
}

注意事项

  • 只要你实例化View时使用的是Application/Activity的Context(遵循Android常规View实例化规范),读取到的就是全局AppTheme中配置的fontFamily值,和系统原生控件的字体完全对齐,不需要额外做全局同步
  • 如果主题未配置android:fontFamily,getFont返回空,直接用Typeface.DEFAULT即可自动回退系统默认字体
  • 使用TypedArrayCompat可以兼容API14及以上版本,不需要额外适配高系统版本

内容的提问来源于stack exchange,提问作者sizzlesmcnizzles

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.07 17:15:01