首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在Stepper中保持状态

在Stepper中保持状态
EN

Stack Overflow用户
提问于 2020-01-08 16:21:58
回答 3查看 1K关注 0票数 2

我的Stepper有多个步骤。当在每个步骤之间移动时,我如何保持步骤的状态?

我已经尝试添加了AutomaticKeepAliveClientMixin,但它仍然不能保持状态:

代码语言:javascript
复制
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,文本字段将重置为空back。

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

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

EN

回答 3

Stack Overflow用户

发布于 2020-01-09 11:57:34

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

解决方案:

List<Step> get stepList => [

  • Reason一样,将你的控制器转换为返回List<Step>TextEditingController,这样做是为了让你的列表能够访问全局控制器作为全局变量:TextEditingController textEditingController = TextEditingController();

  • Give
  1. to你的TextField,如下所示:

TextField(控制器: textEditingController,装饰: InputDecoration(边框: InputBorder.none,hintText:“输入任何内容”),),

现在会发生的是,当你有了TextEditingController,当你的TextField重建时,它将使用控制器来获取值,所以,当你在Step之间切换时,你的TextField值不会重置。

我已经编辑了你的代码,下面是上面提到的修改后的代码:

代码语言:javascript
复制
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;
}

我希望这对你有帮助,如果有任何疑问,请发表意见。如果这个答案对你有帮助,请接受并给它加一票。

票数 3
EN

Stack Overflow用户

发布于 2020-01-09 11:37:49

你可以在下面复制粘贴运行完整代码

您可以使用TextEditingController()

代码片段

代码语言:javascript
复制
 TextEditingController _pageA = TextEditingController();

 Step(
        title: Text("Page A"),
        content: Column(
          children: <Widget>[
            Text("Page A"),
            TextField(
              controller: _pageA,

工作演示

完整代码

代码语言:javascript
复制
import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  TextEditingController _pageA = TextEditingController();
  int currentStep = 0;
  List<Step> stepList;

  @override
  void initState() {
    super.initState();
    stepList = [
      Step(
        title: Text("Page A"),
        content: Column(
          children: <Widget>[
            Text("Page A"),
            TextField(
              controller: _pageA,
              decoration: InputDecoration(
                  border: InputBorder.none, hintText: "Enter anything"),
            ),
          ],
        ),
        state: StepState.indexed,
      ),
      Step(title: Text("Page B"), content: Text("Page B")),
      Step(title: Text("Page C"), content: Text("Page C")),
    ];
  }

  @override
  void dispose() {
    _pageA.dispose();
    super.dispose();
  }

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

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

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

Stack Overflow用户

发布于 2021-03-15 05:44:58

那么,您必须将AutomaticKeepAliveClientMixin与包含stepper的实际小部件一起使用,而不是与steps小部件一起使用。这样,当您在屏幕之间导航时,每个步骤都会得到保留

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59641898

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档