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

如何在Flutter应用中获取设备默认字体并全局使用?

解决Flutter应用适配设备默认字体且不影响原生控件的方案

一、Flutter端正确适配系统字体(无需破坏原生配置)

直接在Flutter主题中让字体继承系统默认,无需修改原生代码:

import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter System Font Demo',
      // 核心配置:不指定 fontFamily,让Flutter自动使用系统默认字体
      theme: ThemeData(
        textTheme: const TextTheme(
          // 可选:针对各文本样式显式使用系统通用字体族
          bodyLarge: TextStyle(fontFamily: 'sans-serif'),
          bodyMedium: TextStyle(fontFamily: 'sans-serif'),
          titleLarge: TextStyle(fontFamily: 'sans-serif'),
        ),
      ),
      home: const MyHomePage(),
    );
  }
}

如果需要更精准适配不同Android版本的系统字体,可以通过PlatformChannel获取原生系统字体名称(避免硬编码):

1. 原生Android端添加方法(仅用于获取字体名称,不修改全局配置)

在MainActivity.kt中添加:

import android.content.Context
import io.flutter.embedding.android.FlutterActivity
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.plugin.common.MethodChannel

class MainActivity : FlutterActivity() {
    private val CHANNEL = "com.example/fontchannel"

    override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
        super.configureFlutterEngine(flutterEngine)
        MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL).setMethodCallHandler { call, result ->
            if (call.method == "getSystemFont") {
                val systemFont = resources.configuration.fontConfig?.fontFamilies?.firstOrNull() ?: "sans-serif"
                result.success(systemFont)
            } else {
                result.notImplemented()
            }
        }
    }
}

2. Flutter端调用获取字体

import 'dart:async';
import 'package:flutter/services.dart';

Future<String?> getSystemFontFromNative() async {
  const platform = MethodChannel('com.example/fontchannel');
  try {
    final String? fontName = await platform.invokeMethod('getSystemFont');
    return fontName;
  } on PlatformException catch (e) {
    return 'sans-serif'; // 异常 fallback 到默认字体
  }
}

// 在ThemeData中使用(注意需在异步场景初始化)
theme: ThemeData(
  fontFamily: await getSystemFontFromNative(),
)

二、避免原生控件字体异常的关键

  • 不要修改原生全局样式:保留res/values/styles.xml中AppTheme的默认配置,不要添加android:fontFamily全局属性,确保原生控件正常继承设备字体。
  • 恢复之前的错误配置:如果之前修改过原生的字体设置,将其还原:
    <!-- 正确的原生样式配置 -->
    <style name="AppTheme" parent="Theme.MaterialComponents.Light.DarkActionBar">
        <!-- 移除任何自定义 android:fontFamily 配置 -->
    </style>
    

三、验证效果

  1. 运行Flutter应用,对比原生应用的字体样式(参考你提供的截图),确认字体一致。
  2. 打开原生控件(如原生Activity、Toast、AlertDialog等),检查字体是否仍为设备默认字体。

内容的提问来源于stack exchange,提问作者Mohammed El Shora

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 00:17:17