问题描述
我有一个名为ToggleButtonsList的无状态小部件,并且我的实例字段之一isSelectedType未设置为final。正因为如此,这是我收到的警告:
“该类(或该类继承的类)被标记为'@immutable',但是其一个或多个实例字段不是最终的:ToggleButtonsList.isSelectedType”
这是我的代码的一部分:
class ToggleButtonsList extends StatefulWidget {
ToggleButtonsList({this.type,this.stringList});
final String type;
final List<String> stringList;
List<bool> isSelectedType = [];
@override
_ToggleButtonsListState createState() => _ToggleButtonsListState();
}
class _ToggleButtonsListState extends State<ToggleButtonsList> {
@override
Widget build(BuildContext context) {
}
}
我的问题:我认为实例字段必须设置为最终的仅适用于无状态小部件,而不适用于有状态小部件。这是真的?这是我应该担心的警告,因为我没有使用StatelessWidget还是可以忽略它?当我忽略警告时,我的应用程序似乎运行正常。
阅读“或该类继承自的类” 的警告部分,使我尝试在我的项目中搜索该类可能继承的任何StatelessWidgets,而我在项目中拥有的唯一StatelessWidget是从我的main.dart中:
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData.dark().copyWith(
primaryColor: Colors.blueGrey,scaffoldBackgroundColor: Colors.blueGrey),home: PriceScreen(),);
}
}
将MyApp类更改为StatefulWidget并没有消除警告。
解决方法
我认为您将State
和StatefulWidget
混合使用。 Widget
类本身是immutable
,并且StatelessWidget
和StatefulWidget
都从Widget
类扩展。
在您的特定情况下,isSelectedType
变量可以为final
,因为最终集合可以增长或收缩。只有恒定的收藏不允许您增长或收缩。
您需要做什么:
class ToggleButtonsList extends StatefulWidget {
ToggleButtonsList({this.type,this.stringList});
final String type;
final List<String> stringList;
@override
_ToggleButtonsListState createState() => _ToggleButtonsListState();
}
class _ToggleButtonsListState extends State<ToggleButtonsList> {
List<bool> isSelectedType = [];
@override
Widget build(BuildContext context) {
}
}
,
有状态和无状态小部件都必须是不可变的。
这是由@immutable
类上的Widget
强制执行的。
请参见Flutter: Mutable fields in stateless widgets:
无状态窗口小部件应仅具有最终字段,无例外。原因:当出于某种原因(屏幕旋转,动画,滚动...)重建父窗口小部件时,将调用父窗口的
build
方法,这将导致所有窗口小部件都被重建。扩展
StatefulWidget
的类必须遵循相同的规则,因为它们也被重构。在布局树的窗口小部件生命周期中,仅保留可包含可变字段的状态。