我试图在SizedBox中创建一个简单的Text小部件来响应AppBar中IconButtons上的水龙头。我复制了早期的一个GridView更新示例(由SO社区提供)的范例(或者我认为)。在此当前应用程序中,将显示当前级别。点击加号图标时,级别应递增。点击重播图标时,级别应重置为1。
在调试过程中,我发现传递给Level_Indicator的级别正在按预期更改。但在Level_Indicator_State中,level中的值始终为1;它永远不会增加,也不会重置。
代码如下。有人请指出我做错了什么吗?谢谢
// ignore_for_file: camel_case_types
// ignore_for_file: constant_identifier_names
// ignore_for_file: non_constant_identifier_names
import 'package:flutter/material.dart';
void main() => runApp(new MyApp());
class Level_Indicator extends StatefulWidget {
final int level;
Level_Indicator(this.level, {Key key}) : super(key: key);
@override // Level_Indicator
Level_Indicator_State createState() => Level_Indicator_State(level);
} // class Level_Indicator
class Level_Indicator_State extends State<Level_Indicator> {
final int level;
Level_Indicator_State(this.level);
@override // Level_Indicator_State
Widget build(BuildContext context) {
return Row(
mainAxisSize: MainAxisSize.min,
children: [
SizedBox(
width: 24.0,
child: Container(
child: Text(
'$level',
style: TextStyle(
color: Colors.blue,
fontWeight: FontWeight.bold,
fontSize: 24.0,
) ,
),
),
),
],
);
}
} // class Level_Indicator_State
class MyApp extends StatefulWidget {
@override
State<StatefulWidget> createState() {
return new MyApp_State();
}
} // class MyApp
class MyApp_State extends State<MyApp> {
int level = 1;
void increment_level ( ){
level++;
setState(() {});
} // increment_level
void reinitialize() {
level = 1;
setState(() {});
} // reinitialize
@override // class MyApp_State
Widget build(BuildContext context) {
return MaterialApp(
title: 'Level Demo',
home: Scaffold(
appBar: AppBar(
title: Text('Level Demo'),
actions: <Widget>[
IconButton(
icon: Icon(Icons.add),
onPressed: () {
increment_level();
},
),
IconButton(
icon: Icon(Icons.replay),
onPressed: () {
reinitialize();
},
),
]
),
body: Center(
child:
Level_Indicator(level)
),
),
);
}
} // class MyApp_State
这个问题有两种解决方案:
Level_Indicator
是一个有状态的小工具?它只是展示给它的东西。没有处理的状态。让它无国籍。
class Level_Indicator extends StatelessWidget {
final int level;
Level_Indicator(this.level);
@override // Level_Indicator_State
Widget build(BuildContext context) {
print("level state");
print("${level}");
return Row(
mainAxisSize: MainAxisSize.min,
children: [
SizedBox(
width: 24.0,
child: Container(
child: Text(
'${level}',
style: TextStyle(
color: Colors.blue,
fontWeight: FontWeight.bold,
fontSize: 24.0,
),
),
),
),
],
);
}
}
Level_Indicator
出于某种原因是有状态的。在这种情况下,level
也不是state
的Level_Indicator_State
变量。所以像下面的widget.level
一样使用它。
class Level_Indicator extends StatefulWidget {
final int level;
Level_Indicator(this.level, {Key key}) : super(key: key);
@override // Level_Indicator
Level_Indicator_State createState() => Level_Indicator_State(level);
} // class Level_Indicator
class Level_Indicator_State extends State<Level_Indicator> {
Level_Indicator_State();
@override // Level_Indicator_State
Widget build(BuildContext context) {
return Row(
mainAxisSize: MainAxisSize.min,
children: [
SizedBox(
width: 24.0,
child: Container(
child: Text(
'${widget.level}',
style: TextStyle(
color: Colors.blue,
fontWeight: FontWeight.bold,
fontSize: 24.0,
) ,
),
),
),
],
);
}
} // class Level_Indicator_State // class Level_Indicator_State
您在level
StatefulWidget以及Level_Indicator
类中定义了Level_Indicator_State
属性。
您不需要通过构造函数将其从Level_Indicator传递给Level_Indicator_State类。你可以从Level_Indicator_State调用widget.level
。
这也意味着Level_Indicator不需要是有状态类。您可以通过将其设置为无状态类来简化此操作(因为您不是在此窗口小部件中更改状态。您正在从MyApp_State创建新的状态。
将Level_Indicator更改为无状态窗口小部件可能会解决此问题,因为StatefulWidget生命周期中存在一些非显而易见的陷阱。
阅读State classes documentation以获取更多信息(特别是对于相同runtimeType和密钥的小部件)。
对于想要从StatefulWidget外部递增计数器(更改状态)的更复杂的情况(并且没有在其状态类中维护该状态),您将需要某种ValueNotifier或Stream来执行此操作而不是仅仅通过中的值。