参考链接

【DAY1-3】零基础Flutter 编译开发 鸿蒙openHarmonyOS

 DAY【4-6】开源鸿蒙Flutter如何搭建GitCode口袋工具

【Day7-10】开源鸿蒙之Flutter 的自定义组件封装(1)

【Day7-10】开源鸿蒙Flutter 常用组件封装实战(2)

【Day7-10】开源鸿蒙组件封装实战(3)仿知乎日报的首页轮播图实现

前言

如果 Day1-6 是把地基打好,那 Day7-10 就是开始盖房子:从 Flutter 自定义组件入门,到跨端封装思路的统一,再到鸿蒙侧复杂业务组件(仿知乎日报轮播 Banner)的完整落地。
这一部分的学习重点是**“组件工程化能力”**:你不只会拼 UI,而是能封装、复用、跨端一致、可维护。


1. Flutter 自定义组件封装基础(Day7-10 1)

1.1 StatelessWidget:无状态组件

无状态组件适合纯展示、无内部可变数据的场景,比如通用按钮、空状态页、标题栏。
基本范式:构造函数参数化 + build 返回组合后的 UI。


class CustomButton extends StatelessWidget { final String text; final VoidCallback onPressed; const CustomButton({required this.text, required this.onPressed}); @override Widget build(BuildContext context) { return ElevatedButton( onPressed: onPressed, child: Text(text), ); } }

封装要点:

  • 结构稳定:按钮的布局、颜色、圆角不随业务各写一遍

  • 可变点参数化:文本/回调作为参数传入

  • 复用成本低:业务里一行调用即可


1.2 StatefulWidget:有状态组件

当组件内部需要管理状态(计数器、表单输入、动画展开/收起)时使用 StatefulWidget。


class CounterWidget extends StatefulWidget { @override State<CounterWidget> createState() => _CounterWidgetState(); } class _CounterWidgetState extends State<CounterWidget> { int _count = 0; void _increment() { setState(() => _count++); } @override Widget build(BuildContext context) { return Column( children: [ Text("count=$_count"), ElevatedButton(onPressed: _increment, child: Text("add")), ], ); } }

理解关键:

  • 状态放在 State 类里

  • setState 是唯一的 UI 更新入口

  • StatefulWidget 本体只负责“创建状态”


1.3 child vs children:新手高频错误

Flutter 的 build 只能 return 一个 Widget
想返回多个子控件,必须放在支持 children 的多子容器中:


return Column( children: [ Text("A"), Text("B"), ], );

速记法:

  • child:只能放一个孩子(Container/Center/Padding)

  • children:可以放多个(Row/Column/ListView)

很多布局报错其实都来自这里。


2. ArkUI 与 Flutter 封装对齐(Day7-10 2)

2.1 ArkUI 组件封装风格

鸿蒙 ArkUI 是声明式 UI:

  • @Component 声明组件

  • @Prop 定义外部输入属性

  • @State 定义内部状态

  • build 描述 UI

这和 Flutter 一样,本质都是“状态驱动界面”,只是语法不同。

2.2 Flutter 封装风格

Flutter 用 Stateless/Stateful + Widget 组合实现同样的思想:

  • 组件结构稳定

  • 可变部分参数化

  • 事件通过回调透出

  • 主题通过 Theme 系统统一


3. 跨端组件库的工程方法论(本阶段最值钱的结论)

文章通过对比两端封装方式,提炼了跨平台统一的三条方法:

  1. 抽象共性接口
    用一层抽象定义共性能力(参数、回调、状态含义)。
    业务层只依赖接口,不要散落平台判断,否则维护地狱。

  2. 平台分流实现
    真正差异化的部分放在实现层,通过 Platform 判断或条件编译分支解决。

  3. 避免高频跨端桥接
    高频交互、动画、手势逻辑尽量留在平台侧,Flutter 侧保持轻 UI。
    这对性能和体验影响巨大。

image_cropper 插件鸿蒙化就是标准流程:抽象能力 → 鸿蒙侧补齐实现 → 签名/构建验证。


4. 鸿蒙端 Banner 轮播(仿知乎日报首页)实战(Day7-10 3)

4.1 为什么选 PageSlider

在 OpenHarmony 里,轮播/翻页的基础组件就是 PageSlider:

  • 自带左右滑动分页能力

  • Provider 提供页面数据

  • Controller 可控制跳页、自动切页
    非常适合封装 Banner。

4.2 数据模型先行

轮播图数据一般包含图片和标题(也可以扩展副标题、跳转链接)。


public class BannerItem { private String imageUrl; private String title; // getter/setter }

先有模型再写 UI,后期扩展字段不会撞墙。

4.3 封装 BannerComponent

核心套路是“固定结构 + 数据注入 + 内部管理逻辑”:

  • BannerComponent 继承 DirectionalLayout

  • 内部持有 PageSlider 和 dataList

  • 对外开放 setData(List<BannerItem>)

  • setData 后 initBanner 绑定 Adapter

这样业务层只关心传数据,不关心轮播内部怎么实现。

4.4 自动轮播

用定时任务每 3 秒切换下一页:

  • current + 1

  • % size 做循环
    并注意:页面不可见时停止轮播,避免耗电和后台无意义刷新。

4.5 指示器(圆点)

底部居中放一排点:

  • 用布局动态生成点数

  • onPageChanged 时刷新选中态
    效果就很接近知乎日报的 Banner 体验。

4.6 点击事件

给每一页注册点击监听,通过 position 回调到外部做跳转或埋点。

4.7 性能优化

文章强调了四点高价值实践:

  1. 图片缓存(减少重复请求)

  2. 不可见即停轮播

  3. Adapter 复用 item view

  4. 网络图压缩/缩略
    这些都是“轮播组件能否上生产”的关键。


5. 总结

Day7-10 完成了三层能力升级:

  • Flutter 侧:从“写页面”升级到“写组件库”

  • 跨端侧:从“分别写两套 UI”升级到“接口抽象 + 分端实现”

  • 鸿蒙侧:从“会用基础组件”升级到“能封装复杂业务组件并稳定运行”

当你掌握了这套路径,后续无论做列表卡片、导航栏、表单控件、或者插件鸿蒙化,都可以按同样套路快速落地。

Logo

作为“人工智能6S店”的官方数字引擎,为AI开发者与企业提供一个覆盖软硬件全栈、一站式门户。

更多推荐