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

Flutter Clean架构项目中富文本个人资料的多端响应式实现咨询

在Clean架构Flutter项目中实现跨端适配的富文本个人资料

一、Clean架构下的职责拆分

在Clean架构里,适配与渲染逻辑完全放在UI层,域层只负责处理个人资料的业务规则(比如数据校验、格式转换),数据层负责从接口/本地获取原始资料数据。这样能保证适配逻辑不侵入核心业务,也方便后续修改适配规则。

二、适配方案优化(基于你已用的LayoutBuilder)

你用LayoutBuilder获取约束是正确方向,这里可以结合MediaQuery和封装响应式工具类,让样式调整更高效:

1. 封装响应式工具类

创建ResponsiveUtils类统一处理尺寸判断与样式计算,避免在UI组件里写大量重复条件:

class ResponsiveUtils {
  static bool isMobile(BuildContext context) {
    return MediaQuery.of(context).size.width < 768;
  }

  static bool isWeb(BuildContext context) {
    return MediaQuery.of(context).size.width >= 1200;
  }

  static double getTextSize(BuildContext context, double mobileSize, double webSize) {
    return isMobile(context) ? mobileSize : webSize;
  }

  static EdgeInsets getPadding(BuildContext context, EdgeInsets mobilePadding, EdgeInsets webPadding) {
    return isMobile(context) ? mobilePadding : webPadding;
  }
}

2. 结合LayoutBuilder动态调整富文本样式

LayoutBuilder能获取父组件约束,适合不确定父组件尺寸时的适配场景(比如侧边栏内的个人资料):

class ProfileRichText extends StatelessWidget {
  final ProfileData profileData; // 从域层传递的已处理数据

  const ProfileRichText({super.key, required this.profileData});

  @override
  Widget build(BuildContext context) {
    return LayoutBuilder(
      builder: (context, constraints) {
        final isMobile = constraints.maxWidth < 768;
        final baseStyle = TextStyle(
          fontSize: isMobile ? 16 : 20,
          fontWeight: FontWeight.w500,
          color: Colors.black87,
        );
        final highlightStyle = TextStyle(
          fontSize: isMobile ? 18 : 22,
          fontWeight: FontWeight.bold,
          color: Colors.blueAccent,
        );

        return RichText(
          text: TextSpan(
            children: [
              TextSpan(text: "姓名:", style: baseStyle),
              TextSpan(text: "${profileData.name}\n", style: highlightStyle),
              TextSpan(text: "职位:", style: baseStyle),
              TextSpan(text: "${profileData.position}\n", style: highlightStyle),
              TextSpan(text: "简介:", style: baseStyle),
              TextSpan(text: profileData.bio, style: baseStyle.copyWith(height: 1.5)),
            ],
          ),
          textAlign: TextAlign.left,
        );
      },
    );
  }
}

三、富文本进阶处理(支持Markdown格式)

如果个人资料需要支持Markdown(加粗、链接、换行等),可以用flutter_markdown包,同时动态调整渲染样式:

class MarkdownProfile extends StatelessWidget {
  final String markdownContent;

  const MarkdownProfile({super.key, required this.markdownContent});

  @override
  Widget build(BuildContext context) {
    return LayoutBuilder(
      builder: (context, constraints) {
        final isMobile = constraints.maxWidth < 768;
        return MarkdownBody(
          data: markdownContent,
          styleSheet: MarkdownStyleSheet(
            p: TextStyle(fontSize: isMobile ? 16 : 18, height: 1.5),
            strong: TextStyle(fontSize: isMobile ? 17 : 19, fontWeight: FontWeight.bold),
            link: TextStyle(fontSize: isMobile ? 16 : 18, color: Colors.blueAccent),
          ),
        );
      },
    );
  }
}

四、Clean架构下的数据流转

  1. 数据层:从API获取原始个人资料数据(如JSON),返回给域层。
  2. 域层:将原始数据转换为ProfileData实体类,处理格式转换(比如把Markdown字符串整理为可渲染格式),不涉及任何适配逻辑。
  3. UI层:通过Presenter/ViewModel从域层获取ProfileData,再用适配组件渲染富文本。

五、额外优化点

  • 搭配OrientationBuilder处理横竖屏切换适配,比如移动端横屏时自动切换为Web端样式。
  • Web端可添加MouseRegion实现hover交互效果,移动端自动隐藏该逻辑:
Widget build(BuildContext context) {
  return LayoutBuilder(
    builder: (context, constraints) {
      final isWeb = constraints.maxWidth >= 1200;
      return isWeb 
          ? MouseRegion(
              onHover: (_) {}, // 这里添加hover时的样式变化逻辑
              child: RichText(...),
            )
          : RichText(...);
    },
  );
}

内容的提问来源于stack exchange,提问作者bv.dev.br

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 07:03:23