在 initState 上声明时 setState 不更新变量
setState not updating variable when declared on initState
我 运行 遇到了 Flutter 的问题:我有一个 navbar
,根据所选的项目,returns 我有一个名为 Index 的整数。然后通过一个List传递这个index得到Scaffold的body内容,一个Widget()
class.
的对象
默认正文是 HomePage()
的对象,它有一个名为 rpm
的整数参数。默认情况下,HomePage()
应该是显示的正文,因此,由于它取决于 rpm
参数,我在 initState
上声明了 rpm
参数。我还有一个 setState
动态改变 rpm
.
奇怪的是:如果我在 initState 中声明 List<Widgets> bodyList
,setState
似乎不起作用。但是,如果我在构建方法中声明 List<Widgets> bodyList
,我可以看到 HomePage()
的内容随 rpm
.
动态变化
代码摘录。不工作:
class _ScreenTreeState extends State<ScreenTree> {
int _index;
int _rpm;
List<Widget> bodyList;
@override
void initState() {
_isPlaying = false;
_rpm = 0;
_index = 0;
bodyList = [
HomePage(rpm: _rpm),
StatisticsScreen(),
WeightScreen(),
SettingsPage()
];
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(...
工作:
class _ScreenTreeState extends State<ScreenTree> {
int _index;
int _rpm;
List<Widget> bodyList;
@override
void initState() {
_isPlaying = false;
_rpm = 0;
_index =
0;
super.initState();
}
@override
Widget build(BuildContext context) {
bodyList = [
HomePage(rpm: _rpm),
StatisticsScreen(),
WeightScreen(),
SettingsPage()
];
return Scaffold(...
我的理论是,这可能与以下事实有关:如果 _rpm
被声明为整数,Dart 会将其作为原始类型而不是整数 class 的对象来读取,所以如果在 initState
上声明,我实际上不是在传递一个对象,而是一个原语。但是我不明白为什么它在 build
方法中声明时有效。
我觉得这无关紧要,但如果有人需要,这里是更新_rpm
值的代码。拜托,不要读太多,因为我觉得它实际上是不相关的,可能会分散注意力和混淆而不是帮助:
onPressed: () {
if (_isPlaying) {
setState(() {
_isPlaying = false;
});
Provider.of<MicrophoneEngine>(context, listen: false)
.stopRecording();
} else {
setState(() {
_isPlaying = true;
});
Provider.of<MicrophoneEngine>(context, listen: false)
.startRecording((rpmCall) {
setState(() {
_rpm = rpmCall;
});
});
}
},
保留小部件的引用是一种不好的做法(如第一个示例),事实上,您根本不需要该列表。
每次使用 setState
时,都会重建小部件并传递新值。在第一个示例中,您每次都从 init 传递 HomePage(rpm: _rpm)
,这就是它不更新的原因。意思是,您不使用更新后的值重建 HomePage
,您只是从 initState 传递 HomePage
,它是用 0
的初始 _rpm
值实例化的。
我 运行 遇到了 Flutter 的问题:我有一个 navbar
,根据所选的项目,returns 我有一个名为 Index 的整数。然后通过一个List传递这个index得到Scaffold的body内容,一个Widget()
class.
默认正文是 HomePage()
的对象,它有一个名为 rpm
的整数参数。默认情况下,HomePage()
应该是显示的正文,因此,由于它取决于 rpm
参数,我在 initState
上声明了 rpm
参数。我还有一个 setState
动态改变 rpm
.
奇怪的是:如果我在 initState 中声明 List<Widgets> bodyList
,setState
似乎不起作用。但是,如果我在构建方法中声明 List<Widgets> bodyList
,我可以看到 HomePage()
的内容随 rpm
.
代码摘录。不工作:
class _ScreenTreeState extends State<ScreenTree> {
int _index;
int _rpm;
List<Widget> bodyList;
@override
void initState() {
_isPlaying = false;
_rpm = 0;
_index = 0;
bodyList = [
HomePage(rpm: _rpm),
StatisticsScreen(),
WeightScreen(),
SettingsPage()
];
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(...
工作:
class _ScreenTreeState extends State<ScreenTree> {
int _index;
int _rpm;
List<Widget> bodyList;
@override
void initState() {
_isPlaying = false;
_rpm = 0;
_index =
0;
super.initState();
}
@override
Widget build(BuildContext context) {
bodyList = [
HomePage(rpm: _rpm),
StatisticsScreen(),
WeightScreen(),
SettingsPage()
];
return Scaffold(...
我的理论是,这可能与以下事实有关:如果 _rpm
被声明为整数,Dart 会将其作为原始类型而不是整数 class 的对象来读取,所以如果在 initState
上声明,我实际上不是在传递一个对象,而是一个原语。但是我不明白为什么它在 build
方法中声明时有效。
我觉得这无关紧要,但如果有人需要,这里是更新_rpm
值的代码。拜托,不要读太多,因为我觉得它实际上是不相关的,可能会分散注意力和混淆而不是帮助:
onPressed: () {
if (_isPlaying) {
setState(() {
_isPlaying = false;
});
Provider.of<MicrophoneEngine>(context, listen: false)
.stopRecording();
} else {
setState(() {
_isPlaying = true;
});
Provider.of<MicrophoneEngine>(context, listen: false)
.startRecording((rpmCall) {
setState(() {
_rpm = rpmCall;
});
});
}
},
保留小部件的引用是一种不好的做法(如第一个示例),事实上,您根本不需要该列表。
每次使用 setState
时,都会重建小部件并传递新值。在第一个示例中,您每次都从 init 传递 HomePage(rpm: _rpm)
,这就是它不更新的原因。意思是,您不使用更新后的值重建 HomePage
,您只是从 initState 传递 HomePage
,它是用 0
的初始 _rpm
值实例化的。