我的步进器有多个步骤。在每个步骤之间移动时如何保持步骤状态?
我曾尝试添加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来拥有一个“全局”变量,以在Step中跟踪TextField的状态,但这意味着我需要约50个类级别的变量,代码看起来太复杂了。这就是为什么我使用AutomaticKeepAliveClientMixin,但是它不起作用。有更好的方法来解决这个问题吗?
答案 0 :(得分:1)
正在发生的事情是,当您从另一个TextField
导航到Step
时,它正在重建,因此值正在重置。
解决方案:
List<Step>
转换为get
的{{1}}就像List<Step>
List<Step> get stepList => [
作为全局变量:TextEditingController
将该控制器交给您的TextEditingController textEditingController = TextEditingController();
,如下所示:
TextField
现在将要发生的是,当您拥有 TextField(
controller: textEditingController,
decoration: InputDecoration(
border: InputBorder.none,
hintText: "Enter anything"
),
),
时,无论何时TextEditingController
进行重建,只要您在TextField
之间进行切换,它将使用控制器来获取值。您的Step
值不会重置。
我已经编辑了您的代码,以下是具有上述更改的代码:
TextField
希望对您有所帮助,如有任何疑问,请发表评论。 如果此答案对您有帮助,请接受并对其进行投票。
答案 1 :(得分:0)
这是Stepper Widget的示例实现。您不必担心保持状态:
class Home extends StatefulWidget {
@override
_HomeState createState() => _HomeState();
}
class _HomeState extends State<Home> {
int currentStep = 0;
List<Step> stepList = [];
@override
void initState() {
stepList = [
Step(
title: Text('Step 1 title'),
content: Text('Step 1 content'),
isActive: currentStep == 0,
),
Step(
title: Text('Step 2 title'),
content: Text('Step 2 content'),
isActive: currentStep == 1,
),
Step(
title: Text('Step 3 title'),
content: Text('Step 3 content'),
isActive: currentStep == 2,
),
];
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('StackOverflow'),
),
resizeToAvoidBottomInset: false,
body: Center(
child: Column(
children: <Widget>[
Text('test'),
Stepper(
currentStep: currentStep,
onStepContinue: nextStep,
onStepCancel: prevStep,
steps: stepList,
)
],
),
)
);
}
void nextStep(){
setState(() {
if(currentStep < stepList.length - 1)
currentStep++;
});
}
void prevStep(){
setState(() {
if(currentStep > 0)
currentStep--;
});
}
}
答案 2 :(得分:0)
您可以在下面复制粘贴运行完整代码
您可以使用TextEditingController()
代码段
TextEditingController _pageA = TextEditingController();
Step(
title: Text("Page A"),
content: Column(
children: <Widget>[
Text("Page A"),
TextField(
controller: _pageA,
工作演示
完整代码
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--;
});
}
}
答案 3 :(得分:0)
好吧,您必须将 AutomaticKeepAliveClientMixin 与具有步进器的实际小部件一起使用,而不是您的步骤小部件。 这样,当您在屏幕之间导航时,每个步骤都会保留