文档状态页Stepper跳转及跨页状态留存实现方法
Stepper组件实现任意跳转+全局状态留存方案
一、支持直接跳转至任意步骤实现
原生Stepper组件本身已经提供了跳转能力,不需要二次封装组件,只要自己接管步骤控制逻辑即可:
- 首先定义记录当前激活步骤索引的变量,注意如果要做跨页面留存,这个变量不要存在Stepper所在页面的局部
State中 - 给Stepper传入
currentStep属性绑定当前激活索引,同时实现onStepTapped回调:用户点击任意步骤标题时,回调会返回被点击的步骤索引,直接更新激活索引变量、触发UI刷新即可完成跳转 - 如果需要做跳转权限校验(比如未完成前置步骤不允许跳转后续步骤),直接在
onStepTapped回调中加判断逻辑即可,比如校验目标索引前的所有步骤是否为已完成状态,符合条件再更新索引 - 建议同时自定义
controlsBuilder接管底部的下一步/上一步按钮逻辑,避免组件默认步进逻辑和自定义跳转逻辑冲突
核心代码示例:
// 从全局状态读取当前激活步骤 final currentStep = globalState.currentAgreementStep; Stepper( currentStep: currentStep, onStepTapped: (int targetIndex) { // 示例校验:仅允许跳转至已完成步骤、或当前步骤的相邻步骤 bool canJump = targetIndex <= globalState.maxFinishedStep + 1; if (canJump) { // 更新全局状态中的激活步骤 globalState.updateCurrentStep(targetIndex); } }, // 自定义底部操作按钮,移除默认逻辑 controlsBuilder: (context, details) { return Padding( padding: const EdgeInsets.only(top: 16), child: Row( children: [ ElevatedButton( onPressed: () { if (currentStep < stepList.length - 1) { globalState.updateCurrentStep(currentStep + 1); // 标记当前步骤已完成 globalState.markStepFinished(currentStep); } }, child: const Text("确认并下一步"), ), const SizedBox(width: 12), if (currentStep > 0) TextButton( onPressed: () { globalState.updateCurrentStep(currentStep - 1); }, child: const Text("返回上一步"), ) ], ), ); }, steps: buildStepListFromGlobalState(), )
二、步骤状态全局持久留存实现
核心思路是不要把步骤状态存在页面局部作用域,按照需求层级选对应方案即可:
- 基础需求:仅要求切换页面后返回状态不丢失,不需要APP重启后留存
直接把所有步骤相关状态(当前激活索引、每个步骤的完成状态、每个步骤填写的表单数据比如home agreement的签署状态)托管到全局状态层即可:- 可以用项目中已有的状态管理方案(Provider/Riverpod/GetX/Bloc都可以),没有的话写个简单的单例类存储状态也能满足需求
- 页面初始化时直接从全局状态读取步骤数据渲染,页面销毁时不要清空全局状态里的步骤数据,下次进入页面直接读取之前存的值,就不会出现状态重置的问题
- 进阶需求:要求APP杀掉重启后步骤状态依然保留
在全局状态托管的基础上,加一层本地持久化兜底:- 每次步骤状态更新时,把步骤数据序列化成JSON格式,写入本地存储(可以用
shared_preferences存简单键值,数据复杂就用轻量本地库存储结构化数据) - APP启动时优先从本地存储读取之前存的步骤数据,初始化全局状态,再进入对应页面即可恢复之前的进度
- 每次步骤状态更新时,把步骤数据序列化成JSON格式,写入本地存储(可以用
避坑提示:不要用路由参数传递步骤状态,路由栈被pop、替换或者重启的时候,路由参数会直接丢失,稳定性远不如全局状态存储。
内容的提问来源于stack exchange,提问作者Minal Suryawanshi
相关产品推荐
相关产品推荐

