在有状态的小部件中,颤振字段不能是最终的
Posted
技术标签:
【中文标题】在有状态的小部件中,颤振字段不能是最终的【英文标题】:Flutter field must not be final in Stateful widget 【发布时间】:2021-07-15 02:33:24 【问题描述】:Flutter 抱怨 _isSelected
,因为它不是 final
。问题是 must not
是最终的,因为它是在 buttonPressed
上更改的...
class SelectionButton extends StatefulWidget
final String title;
final Function(String) onSelectionButtonTap;
bool isSelected;
SelectionButton(
required this.title,
required this.onSelectionButtonTap,
required this.isSelected,
);
@override
_SelectionButtonState createState() => _SelectionButtonState();
class _SelectionButtonState extends State<SelectionButton>
@override
Widget build(BuildContext context)
return Expanded(
child: GestureDetector(
onTap: ()
setState(()
widget.onSelectionButtonTap(widget.title);
widget.isSelected = !widget.isSelected;
);
,
child: Container(
decoration: BoxDecoration(
color: widget.isSelected ? AppColors.primary : AppColors.white,
borderRadius: BorderRadius.circular(
scaleWidth(10),
),
),
child: Center(
child: Text(
widget.title,
textAlign: TextAlign.center,
style: widget.isSelected
? AppTextStyles.h5White
: AppTextStyles.h5Light,
),
),
),
),
);
这是 Flutter 给我的警告:
该类(或该类继承自的类)被标记为“@immutable”,但它的一个或多个实例字段不是最终的:SelectionButton.isSelected
如您所见,我正在更改widget.isSelected
。我对颤振很陌生,不知道为什么颤振在这里抱怨。一切都按预期工作,但我想这不是最佳实践?我该如何解决这个问题?我在这里错过了什么?
【问题讨论】:
【参考方案1】:这是因为您应该在 State 类中操作 isSelected
,而不是 StatefulWidget。您还希望在小部件上保留 Key
参数。将所有变量声明为 final 允许您将类声明为 const。
在 dart 中,const 意味着对象的整个深层状态可以完全在编译时确定,并且对象将被冻结并完全不可变。
我们希望尽可能使用 const。
以下是重构小部件以关闭 Flutter 编译器的方法:
class SelectionButton extends StatefulWidget
final String title;
final Function(String) onSelectionButtonTap;
final bool isSelected;
const SelectionButton(
Key? key,
required this.title,
required this.onSelectionButtonTap,
required this.isSelected,
) : super(key: key);
@override
_SelectionButtonState createState() => _SelectionButtonState();
class _SelectionButtonState extends State<SelectionButton>
bool isSelected = false;
@override
void initState()
super.initState();
isSelected = widget.isSelected;
@override
Widget build(BuildContext context)
return Expanded(
child: GestureDetector(
onTap: ()
setState(()
widget.onSelectionButtonTap(widget.title);
isSelected = !isSelected;
);
,
child: Container(
decoration: BoxDecoration(
color: isSelected ? AppColors.primary : AppColors.white,
borderRadius: BorderRadius.circular(
scaleWidth(10),
),
),
child: Center(
child: Text(
widget.title,
textAlign: TextAlign.center,
style: isSelected
? AppTextStyles.h5White
: AppTextStyles.h5Light,
),
),
),
),
);
【讨论】:
以上是关于在有状态的小部件中,颤振字段不能是最终的的主要内容,如果未能解决你的问题,请参考以下文章
颤振有状态的小部件在热重载和 pushNamed 之后丢失数据