欢迎加入开源鸿蒙跨平台社区: https://openharmonycrossplatform.csdn.net

前言:跨生态开发的新机遇

在移动开发领域,我们总是面临着选择与适配。今天,你的Flutter应用在Android和iOS上跑得正欢,明天可能就需要考虑一个新的平台:HarmonyOS(鸿蒙)。这不是一道选答题,而是很多团队正在面对的现实。

Flutter的优势很明确——写一套代码,就能在两个主要平台上运行,开发体验流畅。而鸿蒙代表的是下一个时代的互联生态,它不仅仅是手机系统,更着眼于未来全场景的体验。将现有的Flutter应用适配到鸿蒙,听起来像是一个“跨界”任务,但它本质上是一次有价值的技术拓展:让产品触达更多用户,也让技术栈覆盖更广。

不过,这条路走起来并不像听起来那么简单。Flutter和鸿蒙,从底层的架构到上层的工具链,都有着各自的设计逻辑。会遇到一些具体的问题:代码如何组织?原有的功能在鸿蒙上如何实现?那些平台特有的能力该怎么调用?更实际的是,从编译打包到上架部署,整个流程都需要重新摸索。
这篇文章想做的,就是把这些我们趟过的路、踩过的坑,清晰地摊开给你看。我们不会只停留在“怎么做”,还会聊到“为什么得这么做”,以及“如果出了问题该往哪想”。这更像是一份实战笔记,源自真实的项目经验,聚焦于那些真正卡住过我们的环节。

无论你是在为一个成熟产品寻找新的落地平台,还是从一开始就希望构建能面向多端的应用,这里的思路和解决方案都能提供直接的参考。理解了两套体系之间的异同,掌握了关键的衔接技术,不仅能完成这次迁移,更能积累起应对未来技术变化的能力。

混合工程结构深度解析

项目目录架构

当Flutter项目集成鸿蒙支持后,典型的项目结构会发生显著变化。以下是经过ohos_flutter插件初始化后的项目结构:

my_flutter_harmony_app/
├── lib/                          # Flutter业务代码(基本不变)
│   ├── main.dart                 # 应用入口
│   ├── home_page.dart           # 首页
│   └── utils/
│       └── platform_utils.dart  # 平台工具类
├── pubspec.yaml                  # Flutter依赖配置
├── ohos/                         # 鸿蒙原生层(核心适配区)
│   ├── entry/                    # 主模块
│   │   └── src/main/
│   │       ├── ets/              # ArkTS代码
│   │       │   ├── MainAbility/
│   │       │   │   ├── MainAbility.ts       # 主Ability
│   │       │   │   └── MainAbilityContext.ts
│   │       │   └── pages/
│   │       │       ├── Index.ets           # 主页面
│   │       │       └── Splash.ets          # 启动页
│   │       ├── resources/        # 鸿蒙资源文件
│   │       │   ├── base/
│   │       │   │   ├── element/  # 字符串等
│   │       │   │   ├── media/    # 图片资源
│   │       │   │   └── profile/  # 配置文件
│   │       │   └── en_US/        # 英文资源
│   │       └── config.json       # 应用核心配置
│   ├── ohos_test/               # 测试模块
│   ├── build-profile.json5      # 构建配置
│   └── oh-package.json5         # 鸿蒙依赖管理
└── README.md

展示效果图片

flutter 实时预览 效果展示
在这里插入图片描述

运行到鸿蒙虚拟设备中效果展示
在这里插入图片描述

目录

功能代码实现

TextOverflowDemo 主组件

TextOverflowDemo 是整个文本溢出处理示例的主容器,负责组织不同类型的文本溢出处理展示,并提供标签页导航和底部导航栏功能。

核心实现

class TextOverflowDemo extends StatefulWidget {
  const TextOverflowDemo({super.key});

  
  State<TextOverflowDemo> createState() => _TextOverflowDemoState();
}

class _TextOverflowDemoState extends State<TextOverflowDemo> {
  int _selectedTabIndex = 0;

  final List<Widget> _tabs = [
    const Tab(text: '单行溢出'),
    const Tab(text: '多行溢出'),
    const Tab(text: '自定义溢出'),
    const Tab(text: '响应式溢出'),
  ];

  final List<Widget> _tabViews = [
    const SingleLineOverflow(),
    const MultiLineOverflow(),
    const CustomOverflow(),
    const ResponsiveOverflow(),
  ];

  
  Widget build(BuildContext context) {
    return DefaultTabController(
      length: _tabs.length,
      child: Scaffold(
        appBar: AppBar(
          title: const Text('文本溢出处理方案'),
          bottom: TabBar(
            tabs: _tabs,
            onTap: (index) {
              setState(() {
                _selectedTabIndex = index;
              });
            },
          ),
        ),
        body: TabBarView(
          children: _tabViews,
        ),
        bottomNavigationBar: BottomNavigationBar(
          items: const [
            BottomNavigationBarItem(
              icon: Icon(Icons.view_headline),
              label: '单行',
            ),
            BottomNavigationBarItem(
              icon: Icon(Icons.view_list),
              label: '多行',
            ),
            BottomNavigationBarItem(
              icon: Icon(Icons.edit),
              label: '自定义',
            ),
            BottomNavigationBarItem(
              icon: Icon(Icons.phone_android),
              label: '响应式',
            ),
          ],
          currentIndex: _selectedTabIndex,
          onTap: (index) {
            setState(() {
              _selectedTabIndex = index;
              DefaultTabController.of(context)?.animateTo(index);
            });
          },
        ),
      ),
    );
  }
}

实现要点

  1. 标签页导航:使用 DefaultTabControllerTabBar 实现顶部标签页切换,方便用户在不同文本溢出处理方式间切换。

  2. 底部导航栏:添加 BottomNavigationBar 与顶部标签页联动,提供更直观的导航方式,增强用户体验。

  3. 状态管理:通过 _selectedTabIndex 变量和 setState 方法管理当前选中的标签页,确保顶部标签页和底部导航栏状态同步。

  4. 组件组织:将不同类型的文本溢出处理抽离为独立组件,通过 _tabViews 列表统一管理,提高代码可维护性。

使用方法

main.dart 文件中,直接将 TextOverflowDemo 作为首页组件返回即可:

class _MyHomePageState extends State<MyHomePage> {
  
  Widget build(BuildContext context) {
    return const TextOverflowDemo();
  }
}

开发注意事项

  • 导航同步:确保顶部标签页和底部导航栏的状态同步,避免用户操作后状态不一致的情况。
  • 组件生命周期:了解 StatefulWidget 的生命周期,合理管理状态,避免不必要的重建。

SingleLineOverflow 单行溢出

SingleLineOverflow 组件演示了单行文本的四种溢出处理方式,包括 Ellipsis、Fade、Clip 和 Visible。

核心实现

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

  
  Widget build(BuildContext context) {
    const String longText = '这是一段很长的文本,用于演示单行文本溢出的处理方式。当文本长度超过容器宽度时,需要进行适当的处理,以确保界面的美观性。';

    return Padding(
      padding: const EdgeInsets.all(16.0),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          const Text('单行文本溢出处理方式:', style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold)),
          const SizedBox(height: 16.0),
          
          const Text('1. Ellipsis(省略号):', style: TextStyle(fontWeight: FontWeight.bold)),
          Container(
            width: double.infinity,
            padding: const EdgeInsets.all(12.0),
            decoration: BoxDecoration(
              border: Border.all(color: Colors.grey),
              borderRadius: BorderRadius.circular(4.0),
            ),
            child: const Text(
              longText,
              overflow: TextOverflow.ellipsis,
              maxLines: 1,
            ),
          ),
          const SizedBox(height: 16.0),
          
          const Text('2. Fade(渐变消失):', style: TextStyle(fontWeight: FontWeight.bold)),
          Container(
            width: double.infinity,
            padding: const EdgeInsets.all(12.0),
            decoration: BoxDecoration(
              border: Border.all(color: Colors.grey),
              borderRadius: BorderRadius.circular(4.0),
            ),
            child: const Text(
              longText,
              overflow: TextOverflow.fade,
              maxLines: 1,
              softWrap: false,
            ),
          ),
          const SizedBox(height: 16.0),
          
          const Text('3. Clip(裁剪):', style: TextStyle(fontWeight: FontWeight.bold)),
          Container(
            width: double.infinity,
            padding: const EdgeInsets.all(12.0),
            decoration: BoxDecoration(
              border: Border.all(color: Colors.grey),
              borderRadius: BorderRadius.circular(4.0),
            ),
            child: const Text(
              longText,
              overflow: TextOverflow.clip,
              maxLines: 1,
              softWrap: false,
            ),
          ),
          const SizedBox(height: 16.0),
          
          const Text('4. Visible(可见):', style: TextStyle(fontWeight: FontWeight.bold)),
          Container(
            width: double.infinity,
            padding: const EdgeInsets.all(12.0),
            decoration: BoxDecoration(
              border: Border.all(color: Colors.grey),
              borderRadius: BorderRadius.circular(4.0),
            ),
            child: const Text(
              longText,
              overflow: TextOverflow.visible,
              maxLines: 1,
              softWrap: false,
            ),
          ),
        ],
      ),
    );
  }
}

实现要点

  1. 溢出处理方式:展示了四种不同的单行文本溢出处理方式,每种方式都有其适用场景:

    • Ellipsis:文本末尾显示省略号,适用于需要明确告知用户文本被截断的场景。
    • Fade:文本末尾渐变消失,适用于对视觉效果要求较高的场景。
    • Clip:直接裁剪文本,适用于对文本完整性要求不高的场景。
    • Visible:文本超出容器边界显示,适用于需要完整显示文本的场景。
  2. 布局结构:使用 ColumnContainer 构建清晰的布局结构,每个溢出处理方式都有独立的展示区域。

  3. 样式设置:为每个展示区域添加边框和内边距,提高视觉效果和可读性。

使用方法

直接在需要使用单行文本溢出处理的地方引入 SingleLineOverflow 组件即可:

const SingleLineOverflow();

开发注意事项

  • softWrap 设置:对于 FadeClip 方式,需要设置 softWrap: false 才能看到预期效果。
  • 容器宽度:确保容器宽度有限制,否则文本不会发生溢出。
  • 选择合适的溢出方式:根据实际业务需求选择合适的溢出处理方式,平衡视觉效果和用户体验。

MultiLineOverflow 多行溢出

MultiLineOverflow 组件演示了多行文本的溢出处理方式,包括不同行数限制的文本溢出和使用 Expanded 自动适应的效果。

核心实现

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

  
  Widget build(BuildContext context) {
    const String longText = '这是一段很长的文本,用于演示多行文本溢出的处理方式。当文本长度超过容器宽度时,需要进行适当的处理,以确保界面的美观性。这种方式适用于需要显示更多文本内容,但又要限制显示行数的场景。';

    return Padding(
      padding: const EdgeInsets.all(16.0),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          const Text('多行文本溢出处理方式:', style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold)),
          const SizedBox(height: 16.0),
          
          const Text('1. 2行文本,末尾省略:', style: TextStyle(fontWeight: FontWeight.bold)),
          Container(
            width: double.infinity,
            padding: const EdgeInsets.all(12.0),
            decoration: BoxDecoration(
              border: Border.all(color: Colors.grey),
              borderRadius: BorderRadius.circular(4.0),
            ),
            child: const Text(
              longText,
              overflow: TextOverflow.ellipsis,
              maxLines: 2,
            ),
          ),
          const SizedBox(height: 16.0),
          
          const Text('2. 3行文本,末尾省略:', style: TextStyle(fontWeight: FontWeight.bold)),
          Container(
            width: double.infinity,
            padding: const EdgeInsets.all(12.0),
            decoration: BoxDecoration(
              border: Border.all(color: Colors.grey),
              borderRadius: BorderRadius.circular(4.0),
            ),
            child: const Text(
              longText,
              overflow: TextOverflow.ellipsis,
              maxLines: 3,
            ),
          ),
          const SizedBox(height: 16.0),
          
          const Text('3. 使用 Expanded 自动适应:', style: TextStyle(fontWeight: FontWeight.bold)),
          Container(
            width: double.infinity,
            height: 120.0,
            padding: const EdgeInsets.all(12.0),
            decoration: BoxDecoration(
              border: Border.all(color: Colors.grey),
              borderRadius: BorderRadius.circular(4.0),
            ),
            child: const Expanded(
              child: Text(
                longText,
                overflow: TextOverflow.ellipsis,
                maxLines: null,
              ),
            ),
          ),
        ],
      ),
    );
  }
}

实现要点

  1. 行数限制:展示了不同行数限制的文本溢出处理,通过 maxLines 属性控制显示的最大行数。

  2. 自动适应:使用 Expanded 组件实现文本在有限高度容器内的自动适应,通过设置 maxLines: null 让文本根据容器高度自动调整显示行数。

  3. 布局结构:与 SingleLineOverflow 类似,使用 ColumnContainer 构建清晰的布局结构。

使用方法

直接在需要使用多行文本溢出处理的地方引入 MultiLineOverflow 组件即可:

const MultiLineOverflow();

开发注意事项

  • 行数设置:根据实际布局空间和文本内容,合理设置 maxLines 的值,避免文本显示过多或过少。
  • 容器高度:对于使用 Expanded 的情况,需要确保父容器有明确的高度限制,否则 Expanded 可能无法正常工作。
  • 性能考虑:对于长文本,设置合适的 maxLines 可以减少渲染开销,提高性能。

CustomOverflow 自定义溢出

CustomOverflow 组件演示了自定义的文本溢出处理方式,包括点击展开/收起和带"查看更多"按钮的效果。

核心实现

class CustomOverflow extends StatefulWidget {
  const CustomOverflow({super.key});

  
  State<CustomOverflow> createState() => _CustomOverflowState();
}

class _CustomOverflowState extends State<CustomOverflow> {
  bool _expanded = false;

  
  Widget build(BuildContext context) {
    const String longText = '这是一段很长的文本,用于演示自定义文本溢出的处理方式。当文本长度超过容器宽度时,我们可以实现一些自定义的交互效果,比如点击展开/收起文本,或者添加"查看更多"按钮等。这种方式可以提供更好的用户体验,让用户可以根据需要选择是否查看完整内容。';

    return Padding(
      padding: const EdgeInsets.all(16.0),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          const Text('自定义文本溢出处理方式:', style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold)),
          const SizedBox(height: 16.0),
          
          const Text('1. 点击展开/收起:', style: TextStyle(fontWeight: FontWeight.bold)),
          Container(
            width: double.infinity,
            padding: const EdgeInsets.all(12.0),
            decoration: BoxDecoration(
              border: Border.all(color: Colors.grey),
              borderRadius: BorderRadius.circular(4.0),
            ),
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                Text(
                  longText,
                  overflow: TextOverflow.ellipsis,
                  maxLines: _expanded ? null : 2,
                ),
                GestureDetector(
                  onTap: () {
                    setState(() {
                      _expanded = !_expanded;
                    });
                  },
                  child: Text(
                    _expanded ? '收起' : '展开',
                    style: const TextStyle(color: Colors.blue),
                  ),
                ),
              ],
            ),
          ),
          const SizedBox(height: 16.0),
          
          const Text('2. 带"查看更多"按钮:', style: TextStyle(fontWeight: FontWeight.bold)),
          Container(
            width: double.infinity,
            padding: const EdgeInsets.all(12.0),
            decoration: BoxDecoration(
              border: Border.all(color: Colors.grey),
              borderRadius: BorderRadius.circular(4.0),
            ),
            child: Stack(
              children: [
                const Text(
                  longText,
                  overflow: TextOverflow.ellipsis,
                  maxLines: 2,
                ),
                Positioned(
                  bottom: 0,
                  right: 0,
                  child: ElevatedButton(
                    onPressed: null,
                    style: ElevatedButton.styleFrom(
                      backgroundColor: Colors.white,
                      foregroundColor: Colors.blue,
                      elevation: 0,
                      padding: EdgeInsets.zero,
                    ),
                    child: const Text('查看更多'),
                  ),
                ),
              ],
            ),
          ),
        ],
      ),
    );
  }
}

实现要点

  1. 点击展开/收起:通过 _expanded 状态变量控制文本是否展开,点击"展开"/"收起"文本切换状态。

  2. 查看更多按钮:使用 StackPositioned 布局,在文本末尾添加"查看更多"按钮,提供更直观的交互方式。

  3. 状态管理:使用 StatefulWidgetsetState 方法管理展开/收起状态,实现动态效果。

使用方法

直接在需要使用自定义文本溢出处理的地方引入 CustomOverflow 组件即可:

const CustomOverflow();

开发注意事项

  • 状态管理:正确使用 StatefulWidgetsetState 方法管理状态,避免状态管理混乱。

  • 布局层次:对于带"查看更多"按钮的实现,需要注意 Stack 布局的层次关系,确保按钮显示在文本上方。

  • 交互反馈:为交互元素添加适当的视觉反馈,如"展开"/"收起"文本的颜色变化,提高用户体验。

  • 性能优化:对于长文本的展开/收起,考虑使用 AnimatedContainer 等组件添加过渡动画,提升视觉效果。

ResponsiveOverflow 响应式溢出

ResponsiveOverflow 组件演示了响应式的文本溢出处理方式,包括根据容器宽度和屏幕尺寸自动调整文本显示方式,以及使用 FittedBox 自动调整字体大小。

核心实现

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

  
  Widget build(BuildContext context) {
    const String longText = '这是一段很长的文本,用于演示响应式文本溢出的处理方式。在不同屏幕尺寸下,文本的显示方式会自动调整,以适应不同的容器宽度。这种方式可以确保在各种设备上都能提供良好的用户体验。';

    return Padding(
      padding: const EdgeInsets.all(16.0),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          const Text('响应式文本溢出处理方式:', style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold)),
          const SizedBox(height: 16.0),
          
          const Text('1. 自适应容器宽度:', style: TextStyle(fontWeight: FontWeight.bold)),
          LayoutBuilder(
            builder: (context, constraints) {
              int maxLines = constraints.maxWidth > 300 ? 3 : 2;
              
              return Container(
                width: double.infinity,
                padding: const EdgeInsets.all(12.0),
                decoration: BoxDecoration(
                  border: Border.all(color: Colors.grey),
                  borderRadius: BorderRadius.circular(4.0),
                ),
                child: Text(
                  longText,
                  overflow: TextOverflow.ellipsis,
                  maxLines: maxLines,
                ),
              );
            },
          ),
          const SizedBox(height: 16.0),
          
          const Text('2. 不同屏幕尺寸的处理:', style: TextStyle(fontWeight: FontWeight.bold)),
          Container(
            width: double.infinity,
            padding: const EdgeInsets.all(12.0),
            decoration: BoxDecoration(
              border: Border.all(color: Colors.grey),
              borderRadius: BorderRadius.circular(4.0),
            ),
            child: MediaQuery.of(context).size.width > 600
                ? const Text(
                    longText,
                    overflow: TextOverflow.visible,
                    softWrap: true,
                  )
                : const Text(
                    longText,
                    overflow: TextOverflow.ellipsis,
                    maxLines: 2,
                  ),
          ),
          const SizedBox(height: 16.0),
          
          const Text('3. 使用 FittedBox 自动调整字体大小:', style: TextStyle(fontWeight: FontWeight.bold)),
          Container(
            width: 200.0,
            height: 60.0,
            padding: const EdgeInsets.all(8.0),
            decoration: BoxDecoration(
              border: Border.all(color: Colors.grey),
              borderRadius: BorderRadius.circular(4.0),
            ),
            child: const FittedBox(
              fit: BoxFit.contain,
              child: Text(
                '这段文本会根据容器大小自动调整字体大小',
                textAlign: TextAlign.center,
              ),
            ),
          ),
        ],
      ),
    );
  }
}

实现要点

  1. 容器宽度适应:使用 LayoutBuilder 组件获取容器宽度约束,根据容器宽度动态调整文本的最大显示行数。

  2. 屏幕尺寸适应:使用 MediaQuery.of(context).size.width 获取屏幕宽度,根据屏幕宽度动态调整文本的溢出处理方式。

  3. 字体大小适应:使用 FittedBox 组件实现文本字体大小的自动调整,通过 fit 属性控制文本如何适应容器大小。

使用方法

直接在需要使用响应式文本溢出处理的地方引入 ResponsiveOverflow 组件即可:

const ResponsiveOverflow();

开发注意事项

  • 布局约束:使用 LayoutBuilder 时,需要确保其 parent 组件有明确的布局约束,否则可能无法获取正确的约束信息。

  • 屏幕尺寸断点:根据实际目标设备的屏幕尺寸,合理设置屏幕尺寸的断点值,确保在各种设备上都能提供良好的显示效果。

  • 字体大小:使用 FittedBox 时,需要注意文本内容的长度,避免文本过长导致字体大小过小,影响可读性。

  • 性能考虑:响应式布局可能会增加布局计算的复杂度,对于复杂页面,需要注意性能优化。

本次开发中容易遇到的问题

  1. 常量表达式错误

    问题描述:在使用 const 关键字时,遇到 “Method invocation is not a constant expression” 错误。

    原因分析:在 CustomOverflow 组件中,ElevatedButton 被包裹在 const Stack 中,但是 ElevatedButton.styleFrom() 方法调用不是一个常量表达式。

    解决方案:将 const Stack 改为 Stack,这样就不再要求其所有子组件都是常量表达式。

    代码示例

    // 错误代码
    child: const Stack(
      children: [
        Text(
          longText,
          overflow: TextOverflow.ellipsis,
          maxLines: 2,
        ),
        Positioned(
          bottom: 0,
          right: 0,
          child: ElevatedButton(
            onPressed: null,
            style: ElevatedButton.styleFrom(
              backgroundColor: Colors.white,
              foregroundColor: Colors.blue,
              elevation: 0,
              padding: EdgeInsets.zero,
            ),
            child: Text('查看更多'),
          ),
        ),
      ],
    ),
    
    // 正确代码
    child: Stack(
      children: [
        const Text(
          longText,
          overflow: TextOverflow.ellipsis,
          maxLines: 2,
        ),
        Positioned(
          bottom: 0,
          right: 0,
          child: ElevatedButton(
            onPressed: null,
            style: ElevatedButton.styleFrom(
              backgroundColor: Colors.white,
              foregroundColor: Colors.blue,
              elevation: 0,
              padding: EdgeInsets.zero,
            ),
            child: const Text('查看更多'),
          ),
        ),
      ],
    ),
    
  2. 文本溢出不生效

    问题描述:设置了 overflow 属性,但文本溢出处理没有生效。

    原因分析:可能的原因包括:

    • 容器宽度没有限制,文本可以无限扩展。
    • 没有设置 maxLines 属性,文本默认会自动换行。
    • 对于 FadeClip 方式,没有设置 softWrap: false

    解决方案

    • 确保容器有明确的宽度限制。
    • 为文本设置合适的 maxLines 值。
    • 对于需要的情况,设置 softWrap: false
  3. 响应式布局失效

    问题描述:响应式文本溢出处理在不同屏幕尺寸下没有按预期工作。

    原因分析:可能的原因包括:

    • LayoutBuilder 的 parent 组件没有明确的布局约束。
    • 屏幕尺寸断点设置不合理。
    • MediaQuery 获取的屏幕尺寸与实际显示区域不符。

    解决方案

    • 确保 LayoutBuilder 的 parent 组件有明确的布局约束。
    • 根据实际目标设备的屏幕尺寸,合理设置断点值。
    • 对于复杂布局,考虑使用 LayoutBuilder 而不是 MediaQuery,以获取更准确的布局约束信息。
  4. 性能问题

    问题描述:文本溢出处理导致页面渲染性能下降。

    原因分析:可能的原因包括:

    • 长文本没有设置合适的 maxLines,导致渲染开销过大。
    • 响应式布局计算过于复杂。
    • 频繁的状态更新导致组件重建。

    解决方案

    • 为长文本设置合适的 maxLines,减少渲染开销。
    • 优化响应式布局计算,避免不必要的计算。
    • 使用 const 构造函数和 const 变量,减少不必要的组件重建。
    • 对于复杂的响应式布局,考虑使用 AnimatedBuilder 等组件优化动画性能。

总结本次开发中用到的技术点

  1. 文本溢出处理

    • 系统提供的溢出处理方式:使用 TextOverflow 枚举值(Ellipsis、Fade、Clip、Visible)实现不同的文本溢出处理效果。
    • 自定义溢出处理:通过状态管理和布局技巧,实现点击展开/收起和带"查看更多"按钮的文本溢出处理效果。
    • 响应式溢出处理:根据容器宽度和屏幕尺寸,动态调整文本的溢出处理方式。
  2. 布局与组件

    • 基础布局组件:使用 ColumnContainerPadding 等基础布局组件构建清晰的页面结构。
    • 高级布局组件:使用 StackPositionedExpandedLayoutBuilder 等高级布局组件实现复杂的布局效果。
    • 特殊布局组件:使用 FittedBox 实现文本字体大小的自动调整。
  3. 状态管理

    • StatefulWidget:使用 StatefulWidget 管理需要动态更新的状态,如 CustomOverflow 中的展开/收起状态。
    • setState:通过 setState 方法触发组件重建,实现状态更新和 UI 刷新。
  4. 导航与交互

    • 标签页导航:使用 DefaultTabControllerTabBar 实现标签页切换,提供直观的导航方式。
    • 底部导航栏:添加 BottomNavigationBar 与标签页联动,增强用户体验。
    • 交互反馈:为交互元素添加适当的视觉反馈,如"展开"/"收起"文本的颜色变化,提高用户体验。
  5. 响应式设计

    • 容器宽度适应:使用 LayoutBuilder 获取容器宽度约束,根据容器宽度动态调整布局。
    • 屏幕尺寸适应:使用 MediaQuery 获取屏幕尺寸,根据屏幕尺寸动态调整布局。
    • 字体大小适应:使用 FittedBox 实现文本字体大小的自动调整。
  6. 性能优化

    • 常量优化:使用 const 构造函数和 const 变量,减少不必要的组件重建。
    • 渲染优化:为长文本设置合适的 maxLines,减少渲染开销。
    • 布局优化:优化布局结构,减少不必要的布局嵌套和计算。
  7. 错误处理与调试

    • 常量表达式错误:理解 const 关键字的使用限制,避免在常量上下文中使用非常量表达式。
    • 布局调试:使用 Flutter 的调试工具,如 “Toggle Debug Paint”,查看布局边界和约束信息,帮助调试布局问题。
    • 响应式调试:在不同屏幕尺寸的模拟器或设备上测试应用,确保响应式布局在各种情况下都能正常工作。

通过本次开发,我们实现了一个功能完整、展示效果良好的文本溢出处理示例应用,涵盖了 Flutter 中文本溢出处理的多种实现方式和使用场景。同时,我们也总结了开发过程中遇到的问题和解决方案,以及使用的技术点,为后续的开发工作提供了参考。

欢迎加入开源鸿蒙跨平台社区: https://openharmonycrossplatform.csdn.net

Logo

开源鸿蒙跨平台开发社区汇聚开发者与厂商,共建“一次开发,多端部署”的开源生态,致力于降低跨端开发门槛,推动万物智联创新。

更多推荐