You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Android中如何通过代码动态设置全局应用字体大小?

当然可以实现全局字体大小的动态调整!我之前做项目时刚好研究过这个需求,给你分享两种实用的方案,都能通过代码在运行时生效:

方案一:修改全局Configuration的字体缩放比例

这个方案最直接,通过调整系统配置里的字体缩放系数,让整个应用的所有文本控件(包括系统自带的控件)都跟着变化。

实现步骤:

  1. 写一个全局工具方法来设置缩放比例:
public static void setGlobalFontScale(Context context, float scale) {
    Resources resources = context.getResources();
    Configuration config = resources.getConfiguration();
    
    // 适配Android 10及以上版本的API变化
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
        config.setFontScale(scale);
    } else {
        config.fontScale = scale;
    }
    
    // 更新资源配置,让设置生效
    resources.updateConfiguration(config, resources.getDisplayMetrics());
}
  1. 在需要调整的地方(比如设置页面的按钮点击事件)调用这个方法,然后重启当前Activity让所有控件重新加载配置:
// 比如设置为默认大小的1.2倍
setGlobalFontScale(getApplicationContext(), 1.2f);
// 重启Activity
finish();
startActivity(getIntent());

优缺点:

  • ✅ 优点:无需修改布局或自定义控件,所有文本控件自动生效
  • ❌ 缺点:会和系统设置里的字体缩放叠加,可能导致字体过大/过小;Android 17+标记updateConfiguration为过时API,但目前仍可正常使用
方案二:自定义主题属性+统一控件基类

这个方案更灵活可控,不会受系统字体设置影响,还能精准控制哪些控件需要调整大小。

实现步骤:

  1. 先在res/values/styles.xml里定义自定义的字体大小属性:
<declare-styleable name="CustomTextSize">
    <attr name="global_text_size" format="dimension" />
</declare-styleable>

<!-- 在你的应用主题里设置默认值 -->
<style name="AppTheme" parent="Theme.MaterialComponents.Light.DarkActionBar">
    <!-- 其他主题属性 -->
    <item name="global_text_size">14sp</item>
</style>
  1. 自定义一个BaseTextView基类,让所有文本控件都继承它,在初始化时读取主题里的字体大小属性:
public class BaseTextView extends TextView {
    public BaseTextView(Context context) {
        super(context);
        init(context);
    }

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

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

    private void init(Context context) {
        // 从当前主题中获取全局字体大小
        TypedValue typedValue = new TypedValue();
        context.getTheme().resolveAttribute(R.attr.global_text_size, typedValue, true);
        float textSize = typedValue.getDimension(context.getResources().getDisplayMetrics());
        setTextSize(TypedValue.COMPLEX_UNIT_PX, textSize);
    }
}
  1. 布局文件里用BaseTextView代替原生的TextView,然后写方法动态修改主题属性:
public static void updateGlobalTextSize(Context context, float sizeInSp) {
    Resources.Theme theme = context.getTheme();
    TypedValue typedValue = new TypedValue();
    typedValue.type = TypedValue.TYPE_DIMENSION;
    typedValue.density = TypedValue.DENSITY_DEFAULT;
    // 将sp转换为对应像素值
    typedValue.data = (int) TypedValue.applyDimension(
        TypedValue.COMPLEX_UNIT_SP, 
        sizeInSp, 
        context.getResources().getDisplayMetrics()
    );
    // 更新主题属性
    theme.setAttribute(R.attr.global_text_size, typedValue);
    
    // 重启Activity让所有控件重新加载主题
    ((Activity) context).finish();
    ((Activity) context).startActivity(((Activity) context).getIntent());
}

优缺点:

  • ✅ 优点:完全独立于系统字体设置,可自定义影响范围;主题属性支持多维度扩展(比如还能加全局颜色、字重等)
  • ❌ 缺点:需要替换所有文本控件为自定义基类,初期有一定的改造工作量
额外注意事项
  • 不管用哪种方案,都要把用户设置的字体大小保存到SharedPreferences里,在ApplicationonCreate方法中读取并应用,确保每次启动应用都保持用户的设置
  • 如果用方案一,若要避免和系统字体缩放冲突,可以先获取系统当前的缩放比例,再基于此调整(比如config.fontScale = systemScale * userScale

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

火山引擎 最新活动