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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 15:03:16