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

如何创建类似Class.of(context)形式的Flutter自定义类

实现方案

你要的CustomTextStyles.of(context)调用形式和Flutter内置Theme.of、Scaffold.of的逻辑完全一致,不需要复杂依赖,按下面的写法实现即可:

最简实现(无额外依赖,开箱即用)

直接定义带私有构造、静态of方法的样式类,在of方法内接收context做动态样式计算,写完就能直接调用:

import 'package:flutter/material.dart';

class CustomTextStyles {
  final TextStyle h1;
  final TextStyle h2;
  final TextStyle bodyRegular;
  final TextStyle caption;

  // 私有构造,禁止外部手动实例化
  const CustomTextStyles._({
    required this.h1,
    required this.h2,
    required this.bodyRegular,
    required this.caption,
  });

  // 核心of方法,接收BuildContext参数
  static CustomTextStyles of(BuildContext context) {
    // 可以直接通过context取主题、屏幕尺寸等全局参数,做响应式适配
    final currentTheme = Theme.of(context);
    final deviceWidth = MediaQuery.sizeOf(context).width;

    return CustomTextStyles._(
      h1: TextStyle(
        fontSize: deviceWidth > 600 ? 32 : 28,
        fontWeight: FontWeight.w700,
        color: currentTheme.colorScheme.onSurface,
      ),
      h2: TextStyle(
        fontSize: deviceWidth > 600 ? 24 : 22,
        fontWeight: FontWeight.w600,
        color: currentTheme.colorScheme.onSurface,
      ),
      bodyRegular: TextStyle(
        fontSize: 14,
        fontWeight: FontWeight.w400,
        color: currentTheme.colorScheme.onSurfaceVariant,
      ),
      caption: TextStyle(
        fontSize: 12,
        fontWeight: FontWeight.w400,
        color: currentTheme.colorScheme.outline,
      ),
    );
  }
}

直接在build方法里调用就行:

Text(
  "页面大标题",
  style: CustomTextStyles.of(context).h1,
)

性能优化版本(全局缓存实例)

如果担心每次调用of都重复创建样式实例,可以搭配InheritedWidget做全局挂载缓存,和Flutter官方Theme的实现逻辑完全对齐:

  • 第一步:定义私有InheritedWidget作为样式的挂载载体
class _CustomTextStylesScope extends InheritedWidget {
  final CustomTextStyles styles;
  const _CustomTextStylesScope({
    required this.styles,
    required super.child,
  });

  @override
  bool updateShouldNotify(covariant _CustomTextStylesScope oldWidget) {
    return styles != oldWidget.styles;
  }
}
  • 第二步:改造样式类,抽离实例创建逻辑,让of方法优先读取缓存
class CustomTextStyles {
  final TextStyle h1;
  final TextStyle h2;
  final TextStyle bodyRegular;
  final TextStyle caption;

  const CustomTextStyles._({
    required this.h1,
    required this.h2,
    required this.bodyRegular,
    required this.caption,
  });

  static CustomTextStyles of(BuildContext context) {
    final scope = context.dependOnInheritedWidgetOfExactType<_CustomTextStylesScope>();
    // 有全局缓存就用缓存,没有就现场创建兜底
    return scope?.styles ?? _createFromContext(context);
  }

  // 抽离样式创建逻辑
  static CustomTextStyles _createFromContext(BuildContext context) {
    final currentTheme = Theme.of(context);
    final deviceWidth = MediaQuery.sizeOf(context).width;

    return CustomTextStyles._(
      h1: TextStyle(
        fontSize: deviceWidth > 600 ? 32 : 28,
        fontWeight: FontWeight.w700,
        color: currentTheme.colorScheme.onSurface,
      ),
      h2: TextStyle(
        fontSize: deviceWidth > 600 ? 24 : 22,
        fontWeight: FontWeight.w600,
        color: currentTheme.colorScheme.onSurface,
      ),
      bodyRegular: TextStyle(
        fontSize: 14,
        fontWeight: FontWeight.w400,
        color: currentTheme.colorScheme.onSurfaceVariant,
      ),
      caption: TextStyle(
        fontSize: 12,
        fontWeight: FontWeight.w400,
        color: currentTheme.colorScheme.outline,
      ),
    );
  }
}
  • 第三步:在App根节点挂载全局样式,注意要用Builder拿MaterialApp内部的context,否则会拿不到Theme、MediaQuery的实例:
class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Builder(
        builder: (innerContext) {
          return _CustomTextStylesScope(
            styles: CustomTextStyles._createFromContext(innerContext),
            child: const HomePage(),
          );
        },
      ),
    );
  }
}

注意:如果不需要响应全局主题、屏幕尺寸变化,也可以直接在类里写固定的静态TextStyle常量,不需要传context,但这种写法无法适配多主题、横竖屏切换的场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 07:45:44