复盘② 开源鸿蒙+Flutter实战复盘(DAY8-14)🔥

Step Two:复杂页面落地·多终端适配·状态保持实战指南

一、前言 📌

如果说 Step One 解决了**「能不能跑起来」,那 Step Two 就是解决「好不好用、稳不稳定、端侧好不好看」**。

本阶段基于 Flutter + 开源鸿蒙分布式架构,完成底部 Tab、首页、三级 Tab 美食页、状态保持、多终端自适应全套复杂页面开发,所有功能均在 DAYU200/Hi3861 开发板、华为 Mate 60 Pro、鸿蒙平板 真机验证通过。

全文依旧无纯步骤流水账,只保留真机踩坑、底层原因、可直接复制的方案。


二、本阶段核心目标 🎯

  1. 实现 底部 Tab + 4 个主页面 完整架构
  2. 解决 Tab 切换页面状态丢失(列表位置、输入框内容)
  3. 完成三级 Tab 联动(复杂业务页面典型场景)
  4. 实现手机/平板/开发板三端自适应布局
  5. 优化开发板性能,避免卡顿、内存溢出
  6. 封装网络、本地存储、路由,形成企业级雏形工程

三、每日实战深度复盘(问题导向+真机验证)📅

1. DAY8:Flutter 布局——鸿蒙多端适配的地基 🧱

核心痛点
固定宽高 → 开发板溢出、平板太松散、真机不协调。

鸿蒙多终端布局铁律

  • 不写死 px,一律用 MediaQuery + 比例适配
  • 屏幕宽度 <300dp → 判定为 DAYU200 开发板(极简布局)
  • 屏幕宽度 300~600dp → 手机(标准布局)
  • 屏幕宽度 >600dp → 平板(加宽布局)
  • 组件嵌套 ≤ 4 层(开发板性能硬限制)

多端自适应关键代码(真机通用)

Widget adaptiveWidget(Widget child) {
  return LayoutBuilder(
    builder: (context, constraints) {
      final screenWidth = MediaQuery.of(context).size.width;
      final isBoard = screenWidth < 300;
      final isTablet = screenWidth > 600;

      return Padding(
        padding: EdgeInsets.symmetric(
          horizontal: isBoard ? 8 : isTablet ? 24 : 16,
          vertical: isBoard ? 4 : isTablet ? 12 : 8,
        ),
        child: child,
      );
    },
  );
}

真机验证
DAYU200 不溢出、手机紧凑、平板舒展,三端完美适配。


2. DAY9–10:底部 Tab 开发——状态保持是灵魂 📌

最大坑
切 Tab → 列表回到顶部、搜索框清空、页面重建。

底层原因
鸿蒙 Flutter 引擎页面回收策略更激进,非活跃页面会被直接销毁。

终极方案(真机稳定)

  1. 页面混入 AutomaticKeepAliveClientMixin
  2. 搭配 IndexedStack 缓存页面
  3. 配合 PageView 实现平滑切换

核心状态保持代码

class _HomePageState extends State<HomePage> with AutomaticKeepAliveClientMixin {
  
  bool get wantKeepAlive => true; // 关键:保持页面状态

  
  Widget build(BuildContext context) {
    super.build(context);
    return Scaffold(...);
  }
}

底部 Tab 主框架(开发板友好)

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

  
  State<MainTabPage> createState() => _MainTabPageState();
}

class _MainTabPageState extends State<MainTabPage> {
  final PageController _pageController = PageController();
  int _currentIndex = 0;

  final List<Widget> _tabPages = const [
    HomePage(),
    FoodPage(),
    MinePage(),
    SettingsPage(),
  ];

  
  Widget build(BuildContext context) {
    return Scaffold(
      body: PageView(
        controller: _pageController,
        physics: const NeverScrollableScrollPhysics(),
        children: _tabPages,
      ),
      bottomNavigationBar: BottomNavigationBar(
        currentIndex: _currentIndex,
        type: BottomNavigationBarType.fixed,
        items: const [
          BottomNavigationBarItem(icon: Icon(Icons.home), label: "首页"),
          BottomNavigationBarItem(icon: Icon(Icons.fastfood), label: "美食"),
          BottomNavigationBarItem(icon: Icon(Icons.person), label: "我的"),
          BottomNavigationBarItem(icon: Icon(Icons.settings), label: "设置"),
        ],
        onTap: (index) {
          setState(() => _currentIndex = index);
          _pageController.jumpToPage(index);
        },
      ),
    );
  }
}

真机验证
连续切换 20 次 Tab,列表位置、输入内容 100% 保留,开发板不卡顿。


3. DAY11:首页开发——智能搜索 + 多端适配 🏠

核心功能

  • 顶部搜索栏(支持历史记录)
  • 本地存储 shared_preferences 缓存历史
  • 开发板/手机/平板布局自适应

高频坑

  • 搜索历史存不进 → 权限没双配置
  • 开发板输入框太小 → 触控难点击

解决方案

  1. 鸿蒙本地存储必须双权限:
    • ohos.permission.READ_USER_STORAGE
    • ohos.permission.WRITE_USER_STORAGE
  2. 开发板端放大输入框高度、扩大点击热区

4. DAY12:美食页——三级 Tab 联动(复杂页面天花板)🍱

业务场景
一级分类:中餐 / 西餐 / 快餐
二级分类:川菜 / 粤菜 / 湘菜…
三级分类:具体菜品

最容易卡的点

  • Tab 切换重复请求
  • 开发板 CPU/内存爆高
  • 滑动冲突、布局错乱

三大优化手段(开发板救命)

  1. 数据缓存:用 Map 缓存已加载数据,不重复请求
  2. 页面缓存IndexedStack 只重建不重绘
  3. 懒加载:只渲染当前可见 Tab 内容

三级 Tab 核心结构

// 简化版三级联动逻辑(真机可跑)
Scaffold(
  body: NestedScrollView(
    headerSliverBuilder: (_, __) => [
      // 一级 Tab
      SliverAppBar(bottom: TabBar(level1Tabs)),
      // 二级 Tab
      SliverPersistentHeader(
        delegate: TabHeaderDelegate(TabBar(level2Tabs)),
      ),
    ],
    body: ValueListenableBuilder(
      valueListenable: level2Index,
      builder: (_, __, ___) {
        return ListView.builder(
          itemCount: currentFoodList.length,
          itemBuilder: (_, index) => FoodItem(data: currentFoodList[index]),
        );
      },
    ),
  ),
)

优化后效果

  • 开发板切换响应 < 500ms
  • 内存占用降低 30%+
  • 列表流畅不抖动

5. DAY13:工程整合——网络/存储/路由统一封装 🧰

本阶段结束,工程正式具备工业级雏形

  • 统一 Dio 网络封装(带重试、异常提示)
  • 统一本地存储工具类
  • 统一路由管理(支持传参、拦截)
  • 统一多端适配工具类
  • 全页面异常兜底(加载中/失败/空数据)

代码全部提交至 AtomGit,支持直接拉取复现。


6. DAY14:第二阶段复盘优化——合规+深度+可发表 ✅

按 CSDN / 鸿蒙社区发文规则,完成三大优化:

  1. 删除纯流程内容(如“点击新建页面”“添加依赖”)
  2. 全部改为问题导向
    问题场景 → 排查 → 底层原因 → 方案 → 验证设备
  3. 补充真机截图、日志、代码对比

四、本阶段高频问题·真机解决方案表 📊

问题场景 底层原因 最终方案 验证设备
Tab 切换状态丢失 鸿蒙页面回收激进 AutomaticKeepAlive + IndexedStack 全设备
开发板文字/图标溢出 固定尺寸不兼容小屏 MediaQuery 动态适配 DAYU200
三级 Tab 巨卡 重绘+重复请求+内存爆 数据缓存 + 懒加载 + 减少嵌套 DAYU200
平板布局太松散 未做大屏适配 宽度 >600dp 自动加宽 鸿蒙平板
搜索历史保存失败 缺少鸿蒙双权限 配置 module.json5 + AndroidManifest 全设备
列表滑动卡顿 嵌套太深、渲染压力大 组件拆分,嵌套 ≤4 层 Hi3861

五、阶段技术沉淀 📚

Step Two 真正掌握的核心能力:

  1. 复杂页面 = 缓存 + 懒加载 + 少嵌套
  2. 多端适配 = 设备判断 + 比例布局 + 热区放大
  3. 鸿蒙 Flutter 性能 = 给开发板做减法
  4. 工程化 = 统一封装 + 异常兜底 + 状态保持

六、阶段总结 📖

Step Two(DAY8–14)是分布式应用的核心成型阶段

  • 一套代码,跑通手机/平板/开发板
  • 复杂页面不再卡顿、不再错乱
  • 状态不再丢失,体验接近原生应用
  • 工程结构清晰,可直接扩展业务

走完这一步,你已经超过 80% 鸿蒙跨端新手


七、下一阶段预告 🚀

复盘③ Step Three(DAY15–19)
全场景动效落地 + 性能自动降级:

  • 页面转场动画
  • 组件点击动效
  • 加载状态动画
  • 开发板低性能自动关闭动画
  • 分布式体验最终闭环
Logo

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

更多推荐