首页 > 解决方案 > 在 Stepper 中保持状态

问题描述

我的步进器中有多个步骤。在每个 Step 之间移动时如何保持 Step 的状态?

我已经尝试添加 AutomaticKeepAliveClientMixin,但它仍然没有保持状态:

class _MyHomePageState extends State<MyHomePage> with AutomaticKeepAliveClientMixin<MyHomePage> {
  int currentStep = 0;
  List<Step> stepList = [
    Step(
      title: Text("Page A"),
      content: Column(
        children: <Widget>[
          Text("Page A"),
          TextField(
            decoration: InputDecoration(
              border: InputBorder.none,
              hintText: "Enter anything"
            ),
          ),
        ],
      )
    ),
    Step(
      title: Text("Page B"),
      content: Text("Page B")
    ),
    Step(
      title: Text("Page C"),
      content: Text("Page C")
    ),
    Step(
      title: Text("Page D"),
      content: Text("Page D")
    ),
    Step(
      title: Text("Page E"),
      content: Text("Page ")
    ),
  ];

  @override
  Widget build(BuildContext context) {
    super.build(context);
    return Scaffold(
      body: Stepper(
        steps: stepList,
        type: StepperType.horizontal,
        currentStep: currentStep,
        onStepContinue: nextStep,
        onStepCancel: cancelStep,
      ),
    );
  }

  void nextStep(){
    setState(() {
      if(currentStep < stepList.length - 1)
        currentStep++;
    });
  }

  void cancelStep(){
    setState(() {
      if(currentStep > 0)
      currentStep--;
    });
  }

  @override
  bool get wantKeepAlive => true;
}

如果我在文本字段中添加任何内容,导航到 PageB,然后导航回 PageA,文本字段将重置为空。

如何保持每个步骤的“页面”的状态?

编辑:可能应该早点披露这一点。我有 5 个步骤,每个步骤包含 8-12 个字段,包括文本字段、复选框、下拉列表等。这是一个多步骤表单。我知道你可以创建一个类级别的 TextFieldController 来拥有一个“全局”变量来跟踪 TextField 在 Step 中的状态,但这意味着我需要大约 50 个类级别的变量,代码看起来太复杂了。这就是我使用 AutomaticKeepAliveClientMixin 的原因,但它不起作用。有没有更好的方法来处理这个?

标签: flutter

解决方案


正在发生的事情是TextField,当您从另一个导航到它时,您正在重建Step,因此价值正在重置。

解决方案:

  1. 将您的回报转换List<Step>getList<Step>List<Step> get stepList => [
  2. 这样做的原因是让您的列表能够访问全局变量。
  3. 创建一个TextEditingController全局变量:TextEditingController textEditingController = TextEditingController();
  4. 将该控制器提供给您TextField,如下所示:

      TextField(
        controller: textEditingController,
        decoration: InputDecoration(
          border: InputBorder.none,
          hintText: "Enter anything"
        ),
      ),
    

现在将会发生的是,当您拥有 时TextEditingController,无论何时重建它都会使用控制器来获取值,因此,每当您在sTextField之间切换时,您的值都不会重置。StepTextField

我已经编辑了您的代码,以下是具有上述更改的代码:

class _MyHomePageState extends State<MyHomePage> with AutomaticKeepAliveClientMixin<MyHomePage> {
  int currentStep = 0;

  TextEditingController textEditingController = TextEditingController();

  List<Step> get stepList => [
    Step(
      title: Text("Page A"),
      content: Column(
        children: <Widget>[
          Text("Page A"),
          TextField(
            controller: textEditingController,
            decoration: InputDecoration(
              border: InputBorder.none,
              hintText: "Enter anything"
            ),
          ),
        ],
      )
    ),
    Step(
      title: Text("Page B"),
      content: Text("Page B")
    ),
    Step(
      title: Text("Page C"),
      content: Text("Page C")
    ),
    Step(
      title: Text("Page D"),
      content: Text("Page D")
    ),
    Step(
      title: Text("Page E"),
      content: Text("Page ")
    ),
  ];

  @override
  Widget build(BuildContext context) {
    super.build(context);
    return Scaffold(
      body: Stepper(
        steps: stepList,
        type: StepperType.horizontal,
        currentStep: currentStep,
        onStepContinue: nextStep,
        onStepCancel: cancelStep,
      ),
    );
  }

  void nextStep(){
    setState(() {
      if(currentStep < stepList.length - 1)
        currentStep++;
    });
  }

  void cancelStep(){
    setState(() {
      if(currentStep > 0)
      currentStep--;
    });
  }

  @override
  bool get wantKeepAlive => true;
}

希望对你有帮助,如有疑问请留言。如果此答案对您有帮助,请接受并投票。


推荐阅读