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

如何通过MediaQuery结合if语句在ThemeData中动态设置字体大小?

问题解答

可行性说明

完全可以通过屏幕尺寸动态设置ThemeData中的字体大小,只是需要注意获取屏幕尺寸的时机,避免上下文报错问题。

报错原因

你在MyApp的build方法中调用MediaQuery.of(context)时,当前context属于MyApp组件,而MyApp的父级并没有提供MediaQuery(MediaQuery是由MaterialApp内部注入的上下文数据),因此无法通过这个context获取到屏幕尺寸信息,导致报错。

实现方案

方案一:无需上下文,直接通过系统窗口获取屏幕尺寸

适合仅在初始化时设置字体大小,不需要响应屏幕旋转等动态变化的场景。

修改后的代码:

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

  @override
  Widget build(BuildContext context) {
    // 获取屏幕逻辑尺寸(去除设备像素比影响)
    final window = WidgetsBinding.instance.window;
    final screenSize = window.physicalSize / window.devicePixelRatio;
    final screenWidth = screenSize.width;

    // 自定义字体大小规则:屏幕宽度小于360时用14,否则用16
    final bodyTextFontSize = screenWidth < 360 ? 14.0 : 16.0;

    return MaterialApp(
      theme: ThemeData.dark().copyWith(
        scaffoldBackgroundColor: Colors.black,
        textTheme: TextTheme(
          bodyText1: TextStyle(
            fontWeight: FontWeight.bold,
            fontFamily: 'SourceSansPro',
            fontSize: bodyTextFontSize,
          ),
        ),
      ),
      debugShowCheckedModeBanner: false,
      initialRoute: '/second',
      routes: {
        '/': (context) => pageone(),
        '/first': (context) => pagetwo(),
        '/second': (context) => pagethree(),
      },
    );
  }
}

方案二:通过Builder获取有效上下文,响应屏幕动态变化

适合需要在屏幕尺寸改变(比如旋转)时自动更新字体大小的场景。

修改后的代码:

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

  @override
  Widget build(BuildContext context) {
    return Builder(
      builder: (context) {
        // 此时的context已包含MaterialApp提供的MediaQuery数据
        final screenSize = MediaQuery.of(context).size;
        final bodyTextFontSize = screenSize.width < 360 ? 14.0 : 16.0;

        return MaterialApp(
          theme: ThemeData.dark().copyWith(
            scaffoldBackgroundColor: Colors.black,
            textTheme: TextTheme(
              bodyText1: TextStyle(
                fontWeight: FontWeight.bold,
                fontFamily: 'SourceSansPro',
                fontSize: bodyTextFontSize,
              ),
            ),
          ),
          debugShowCheckedModeBanner: false,
          initialRoute: '/second',
          routes: {
            '/': (context) => pageone(),
            '/first': (context) => pagetwo(),
            '/second': (context) => pagethree(),
          },
        );
      },
    );
  }
}

补充说明

  • 方案一的优势是初始化性能更高,但不会自动响应屏幕尺寸的动态变化;
  • 方案二会在屏幕尺寸改变时自动重建MaterialApp,从而更新字体大小,适配更灵活;
  • 如果需要全局所有文本样式都适配屏幕尺寸,只需在TextTheme的其他样式(如bodyText2、headline6等)中复用相同的字体大小判断逻辑即可。

内容的提问来源于stack exchange,提问作者Nomad09

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 00:20:32