如何将数据传递到 initState 内定义的屏幕?
how to Pass data to a screen defined inside initState?
我试图制作一个带有两个随索引变化的视图的屏幕。
我像这样在 initState 中创建了 _pages 列表。
class AddPlan extends StatefulWidget {
static const routeName = "addPlan";
@override
_AddPlanState createState() => _AddPlanState();
}
class _AddPlanState extends State<AddPlan> {
List<Object>? _pages;
int _selectedIndex = 0;
Map<dynamic, dynamic> _stepVals = {};
_setSelectedIndex(int newIndex, Map<dynamic, dynamic> newMap) {
setState(() {
_stepVals = {..._stepVals, ...newMap};
_selectedIndex = newIndex;
});
}
@override
void initState() {
// TODO: implement initState
_pages = [
StepOne(_setSelectedIndex),
StepTwo(_stepVals, _setSelectedIndex)
];
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
elevation: 0,
backgroundColor: Colors.transparent,
),
body: Container(
margin: EdgeInsets.only(top: 10),
padding: EdgeInsets.symmetric(horizontal: 10),
child: _pages![_selectedIndex] as Widget,
),
);
}
}
从 StepOne() 小部件我调用它来传递数据和更改索引。
widget.setNewIndex 是我的 _setSelectedIndex 函数。在我的 StepOne 构造函数中更改了名称。
ElevatedButton(
onPressed: () {
if (_formKey.currentState!.validate()) {
_formKey.currentState!.save();
widget.setNewIndex(1, {
"title": title,
"age": age,
"description": description,
"dificulty": _dificultyIndex,
"targetMuscles": _targetMuscles,
"weekDays": indexList,
});
}
},
child: Container(height: 50, child: Center(child: Text("Next"))),
)
这很好用。它更改了主屏幕内的 _stepVals 变量和 _selectedIndex。
它还将小部件更改为 StepTwo()。但是 StepTwo 小部件没有采用 _stepVals 的 nw 值。它似乎正在使用它在 initState 中收到的 _stepVals 的初始值。我在这里错过了什么吗?我是该语言的新手,所以请提供任何帮助。
您需要将此代码添加到您的 setState
或更高版本才能使其正常工作:
setState(() {
// You only need this:
_pages = [
StepOne(_setSelectedIndex),
StepTwo(_stepVals, _setSelectedIndex)
];
// Or this:
_pages![1] = StepTwo(_stepVals, _setSelectedIndex);
_stepVals = {..._stepVals, ...newMap};
_selectedIndex = newIndex;
});
因为 initState
不会在小部件重建时调用,它只会在第一次构建小部件时调用,所以您需要再次设置 StepTwo
小部件才能使其工作。
另一种方式:
您可以创建这样的函数:
Widget getStep(int index) {
switch (index) {
case 0:
return StepOne(index);
case 1:
return StepTwo(_stepVals, index);
}
}
然后将 getStep
添加到您的 build
:
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
elevation: 0,
backgroundColor: Colors.transparent,
),
body: Container(
margin: EdgeInsets.only(top: 10),
padding: EdgeInsets.symmetric(horizontal: 10),
child: getStep(_selectedIndex),
),
);
}
并使用你的 setState
:
setState(() {
_stepVals = {..._stepVals, ...newMap};
_selectedIndex = newIndex;
});
您不需要 initState
任何变量。
我试图制作一个带有两个随索引变化的视图的屏幕。 我像这样在 initState 中创建了 _pages 列表。
class AddPlan extends StatefulWidget {
static const routeName = "addPlan";
@override
_AddPlanState createState() => _AddPlanState();
}
class _AddPlanState extends State<AddPlan> {
List<Object>? _pages;
int _selectedIndex = 0;
Map<dynamic, dynamic> _stepVals = {};
_setSelectedIndex(int newIndex, Map<dynamic, dynamic> newMap) {
setState(() {
_stepVals = {..._stepVals, ...newMap};
_selectedIndex = newIndex;
});
}
@override
void initState() {
// TODO: implement initState
_pages = [
StepOne(_setSelectedIndex),
StepTwo(_stepVals, _setSelectedIndex)
];
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
elevation: 0,
backgroundColor: Colors.transparent,
),
body: Container(
margin: EdgeInsets.only(top: 10),
padding: EdgeInsets.symmetric(horizontal: 10),
child: _pages![_selectedIndex] as Widget,
),
);
}
}
从 StepOne() 小部件我调用它来传递数据和更改索引。 widget.setNewIndex 是我的 _setSelectedIndex 函数。在我的 StepOne 构造函数中更改了名称。
ElevatedButton(
onPressed: () {
if (_formKey.currentState!.validate()) {
_formKey.currentState!.save();
widget.setNewIndex(1, {
"title": title,
"age": age,
"description": description,
"dificulty": _dificultyIndex,
"targetMuscles": _targetMuscles,
"weekDays": indexList,
});
}
},
child: Container(height: 50, child: Center(child: Text("Next"))),
)
这很好用。它更改了主屏幕内的 _stepVals 变量和 _selectedIndex。 它还将小部件更改为 StepTwo()。但是 StepTwo 小部件没有采用 _stepVals 的 nw 值。它似乎正在使用它在 initState 中收到的 _stepVals 的初始值。我在这里错过了什么吗?我是该语言的新手,所以请提供任何帮助。
您需要将此代码添加到您的 setState
或更高版本才能使其正常工作:
setState(() {
// You only need this:
_pages = [
StepOne(_setSelectedIndex),
StepTwo(_stepVals, _setSelectedIndex)
];
// Or this:
_pages![1] = StepTwo(_stepVals, _setSelectedIndex);
_stepVals = {..._stepVals, ...newMap};
_selectedIndex = newIndex;
});
因为 initState
不会在小部件重建时调用,它只会在第一次构建小部件时调用,所以您需要再次设置 StepTwo
小部件才能使其工作。
另一种方式:
您可以创建这样的函数:
Widget getStep(int index) {
switch (index) {
case 0:
return StepOne(index);
case 1:
return StepTwo(_stepVals, index);
}
}
然后将 getStep
添加到您的 build
:
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
elevation: 0,
backgroundColor: Colors.transparent,
),
body: Container(
margin: EdgeInsets.only(top: 10),
padding: EdgeInsets.symmetric(horizontal: 10),
child: getStep(_selectedIndex),
),
);
}
并使用你的 setState
:
setState(() {
_stepVals = {..._stepVals, ...newMap};
_selectedIndex = newIndex;
});
您不需要 initState
任何变量。