如何在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>
三、验证效果
- 运行Flutter应用,对比原生应用的字体样式(参考你提供的截图),确认字体一致。
- 打开原生控件(如原生Activity、Toast、AlertDialog等),检查字体是否仍为设备默认字体。
内容的提问来源于stack exchange,提问作者Mohammed El Shora
相关产品推荐
相关产品推荐

