Flutter全局字体缩放实现:自定义按钮实现100%-200%字体缩放
实现Flutter全局文本字号调节功能
下面是一套完整的实现方案,能快速添加全局字号调节按钮,支持100%到200%的字号缩放,效果类似安卓系统的字体大小调节:
1. 实现字号状态管理类
用ChangeNotifier管理全局字号缩放比例,方便跨组件同步状态:
import 'package:flutter/material.dart'; class FontSizeManager extends ChangeNotifier { double _textScaleFactor = 1.0; // 默认100% final double _minScale = 1.0; final double _maxScale = 2.0; // 最大200% double get textScaleFactor => _textScaleFactor; // 设置缩放比例,限制在1.0-2.0之间 void setScale(double scale) { if (scale >= _minScale && scale <= _maxScale) { _textScaleFactor = scale; notifyListeners(); } } // 步进放大(每次+20%) void increaseScale() { setScale((_textScaleFactor + 0.2).clamp(_minScale, _maxScale)); } // 步进缩小(每次-20%) void decreaseScale() { setScale((_textScaleFactor - 0.2).clamp(_minScale, _maxScale)); } }
2. 在应用顶层注入状态并全局生效
通过ChangeNotifierProvider将状态注入应用,同时修改MediaQuery的textScaleFactor,让所有依赖系统文本样式的组件自动适配:
import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; void main() { runApp( ChangeNotifierProvider( create: (context) => FontSizeManager(), child: const MyApp(), ), ); } class MyApp extends StatelessWidget { const MyApp({super.key}); @override Widget build(BuildContext context) { return Consumer<FontSizeManager>( builder: (context, fontSizeManager, child) { return MaterialApp( title: '全局字号调节', theme: ThemeData(primarySwatch: Colors.blue), home: const HomePage(), // 全局覆盖MediaQuery的文本缩放因子 builder: (context, child) { return MediaQuery( data: MediaQuery.of(context).copyWith( textScaleFactor: fontSizeManager.textScaleFactor, ), child: child!, ); }, ); }, ); } }
3. 添加调节按钮和交互界面
在页面中实现按钮和滑块,让用户可以直观调整字号:
class HomePage extends StatelessWidget { const HomePage({super.key}); @override Widget build(BuildContext context) { final fontSizeManager = Provider.of<FontSizeManager>(context); return Scaffold( appBar: AppBar(title: const Text('全局字号调节示例')), body: Padding( padding: const EdgeInsets.all(16.0), child: Column( crossAxisAlignment: CrossAxisAlignment.center, children: [ // 测试文本,自动适配全局字号 Text( '这是大标题文本', style: Theme.of(context).textTheme.headlineMedium, ), const SizedBox(height: 16), Text( '这是普通正文文本,字号会随全局设置变化', style: Theme.of(context).textTheme.bodyLarge, ), const SizedBox(height: 24), // 显示当前缩放比例 Text( '当前字号:${(fontSizeManager.textScaleFactor * 100).toInt()}%', style: Theme.of(context).textTheme.titleMedium, ), const SizedBox(height: 32), // 步进调节按钮 Row( mainAxisAlignment: MainAxisAlignment.center, children: [ ElevatedButton( onPressed: fontSizeManager.decreaseScale, child: const Text('缩小'), ), const SizedBox(width: 20), ElevatedButton( onPressed: fontSizeManager.increaseScale, child: const Text('放大'), ), ], ), const SizedBox(height: 24), // 精细调节滑块 Slider( value: fontSizeManager.textScaleFactor, min: 1.0, max: 2.0, divisions: 5, // 分成5档:100%、120%...200% label: '${(fontSizeManager.textScaleFactor * 100).toInt()}%', onChanged: fontSizeManager.setScale, ), ], ), ), ); } }
关键注意点
- 自定义
TextStyle如果写了固定fontSize,需要手动乘以MediaQuery.of(context).textScaleFactor才能同步缩放,比如:TextStyle(fontSize: 16 * MediaQuery.of(context).textScaleFactor) - 第三方UI组件大多会自动适配
MediaQuery的缩放因子,少数特殊组件可能需要单独处理。 - 可以把缩放比例持久化到
SharedPreferences,实现重启应用后保留设置。
内容的提问来源于stack exchange,提问作者Maciek
相关产品推荐
相关产品推荐

