Flutter应用中自定义字号(按需调字体高度)实现方法咨询
Flutter 实现用户自定义字号调整功能
核心思路
通过状态管理维护用户选择的字号选项,再封装一个全局可用的文本组件,自动读取当前选中的字号(及行高)渲染内容。以下是具体实现步骤:
1. 实现字号状态管理
创建状态管理类,保存用户选择的字号选项并提供更新方法:
import 'package:flutter/foundation.dart'; // 预设字号选项 enum FontSizeOption { small, normal, large, extraLarge } class FontSizeManager extends ChangeNotifier { // 默认选中正常字号 FontSizeOption _selectedOption = FontSizeOption.normal; FontSizeOption get selectedOption => _selectedOption; // 映射选项到具体字号值(可按需自定义) double get currentFontSize { switch (_selectedOption) { case FontSizeOption.small: return 12; case FontSizeOption.normal: return 14; case FontSizeOption.large: return 16; case FontSizeOption.extraLarge: return 18; } } // 可选:映射选项到对应行高 double get currentLineHeight { switch (_selectedOption) { case FontSizeOption.small: return 1.2; case FontSizeOption.normal: return 1.4; case FontSizeOption.large: return 1.6; case FontSizeOption.extraLarge: return 1.8; } } void updateFontSize(FontSizeOption newOption) { _selectedOption = newOption; notifyListeners(); } }
2. 在应用顶层注入状态
用ChangeNotifierProvider包裹整个应用,让所有子组件能访问字号状态:
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 MaterialApp( home: const HomePage(), ); } }
3. 构建字号选择界面
提供用户选择字号的UI,比如单选列表:
class FontSizeSettingsPage extends StatelessWidget { const FontSizeSettingsPage({super.key}); @override Widget build(BuildContext context) { final fontSizeManager = Provider.of<FontSizeManager>(context); return Scaffold( appBar: AppBar(title: const Text('调整字号')), body: ListView( children: [ RadioListTile<FontSizeOption>( title: const Text('小号'), value: FontSizeOption.small, groupValue: fontSizeManager.selectedOption, onChanged: (value) { if (value != null) { fontSizeManager.updateFontSize(value); Navigator.pop(context); } }, ), RadioListTile<FontSizeOption>( title: const Text('默认'), value: FontSizeOption.normal, groupValue: fontSizeManager.selectedOption, onChanged: (value) { if (value != null) { fontSizeManager.updateFontSize(value); Navigator.pop(context); } }, ), RadioListTile<FontSizeOption>( title: const Text('大号'), value: FontSizeOption.large, groupValue: fontSizeManager.selectedOption, onChanged: (value) { if (value != null) { fontSizeManager.updateFontSize(value); Navigator.pop(context); } }, ), RadioListTile<FontSizeOption>( title: const Text('超大号'), value: FontSizeOption.extraLarge, groupValue: fontSizeManager.selectedOption, onChanged: (value) { if (value != null) { fontSizeManager.updateFontSize(value); Navigator.pop(context); } }, ), ], ), ); } }
4. 封装自适应文本组件
创建自定义Text组件,自动读取当前选中的字号和行高:
class ScalableText extends StatelessWidget { final String text; final TextStyle? style; final TextAlign? textAlign; final int? maxLines; const ScalableText( this.text, { super.key, this.style, this.textAlign, this.maxLines, }); @override Widget build(BuildContext context) { final fontSizeManager = Provider.of<FontSizeManager>(context); return Text( text, textAlign: textAlign, maxLines: maxLines, style: style?.copyWith( fontSize: fontSizeManager.currentFontSize, height: fontSizeManager.currentLineHeight, ) ?? TextStyle( fontSize: fontSizeManager.currentFontSize, height: fontSizeManager.currentLineHeight, ), ); } }
5. 在页面中使用
用ScalableText替代普通Text,字号会跟随用户选择自动变化:
class HomePage extends StatelessWidget { const HomePage({super.key}); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const ScalableText('首页'), actions: [ IconButton( icon: const Icon(Icons.settings), onPressed: () { Navigator.push( context, MaterialPageRoute(builder: (context) => const FontSizeSettingsPage()), ); }, ), ], ), body: Padding( padding: const EdgeInsets.all(16.0), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: const [ ScalableText( '这是一段自适应字号的文本内容,用户选择不同的字号选项后,这段文字的大小和行高会自动调整。', textAlign: TextAlign.justify, ), SizedBox(height: 20), ScalableText( '标题文本', style: TextStyle(fontWeight: FontWeight.bold), ), ], ), ), ); } }
补充说明
- 若需持久化用户的字号选择,可在
FontSizeManager中加入本地存储逻辑(如shared_preferences),启动时读取上次保存的选项。 - 若项目使用其他状态管理方案(如Riverpod、Bloc),可将字号状态迁移至对应方案,核心逻辑保持一致。
内容的提问来源于stack exchange,提问作者Jaimin Modi
相关产品推荐
相关产品推荐

