颤音:我的自定义开关小部件对状态变化没有响应
我制作了一个自定义的开关窗口小部件,以避免代码重复,该重复是基于带有布尔值的状态灯,所以这很简单:
class SwitchTile extends StatefulWidget
{
final String title;
final bool value;
final ValueChanged<bool> onChanged;
const SwitchTile({Key? key, required this.title, required this.value, required this.onChanged}) : super(key: key);
@override
State<StatefulWidget> createState() => _SwitchTileState();
}
class _SwitchTileState extends State<SwitchTile>
{
late bool value;
@override
void initState()
{
super.initState();
this.value = widget.value;
}
@override
Widget build(BuildContext context)
{
return ListTile(
title: Text(widget.title),
trailing: Switch.adaptive(
value: this.value,
onChanged: (newValue) {
widget.onChanged(newValue);
this.setState(() => this.value = newValue);
}
)
);
}
@override
void dispose()
{
super.dispose();
}
}
现在,我想将某些switchtile窗口小部件与另一个布尔值同步,但是当值更改时,它不会重建它为我期望。我使用flutter_bloc,bloc/events/state效果很好。看看我尝试做的事情:
// See my Widget build() method ; bloc variable is declared above
BlocBuilder<ChadsVascBloc, ChadsVascState>(
builder: (BuildContext context, ChadsVascState state)
{
return Column(
children: [
// this works very well
ListTile(
title: Text("Switch : ageOver65 is ${state.ageOver65.toString()}"),
trailing: Switch.adaptive(
value: state.ageOver65,
onChanged: (value) => bloc.add(AgeOver65Toggled(ageOver65: value))
)
),
// this is does not
SwitchTile(
// the change is well triggered in the title property !!!
title: "SwitchTile : ageOver65 is ${state.ageOver65.toString()}",
value: state.ageOver65, // but this does not change the button's status
onChanged: (value) => bloc.add(AgeOver65Toggled(ageOver65: value))
)
]
);
}
),
SwitchTile(
title: AppLocalizations.of(context)!.ageOver65,
value: bloc.state.ageOver65,
onChanged: (value) => bloc.add(AgeOver65Toggled(ageOver65: value)),
)
当我按下最后一个按钮时,第一个按钮很好地工作(“基本”开关小部件),但是第二个按钮(“基本”开关小部件(自定义的开关窗口小部件)不会:标题更改,但不会更改按钮的位置。
我做错了什么?
I made a custom SwitchTile widget to avoid code duplication, which is based on a StatefulWidget with a boolean value so this is quiet simple :
class SwitchTile extends StatefulWidget
{
final String title;
final bool value;
final ValueChanged<bool> onChanged;
const SwitchTile({Key? key, required this.title, required this.value, required this.onChanged}) : super(key: key);
@override
State<StatefulWidget> createState() => _SwitchTileState();
}
class _SwitchTileState extends State<SwitchTile>
{
late bool value;
@override
void initState()
{
super.initState();
this.value = widget.value;
}
@override
Widget build(BuildContext context)
{
return ListTile(
title: Text(widget.title),
trailing: Switch.adaptive(
value: this.value,
onChanged: (newValue) {
widget.onChanged(newValue);
this.setState(() => this.value = newValue);
}
)
);
}
@override
void dispose()
{
super.dispose();
}
}
Now I want to synchronize some SwitchTile widget with another boolean value, but when the value changes it does not rebuild as I expected. I use flutter_bloc, the bloc/events/states work very well. See what I tried to do :
// See my Widget build() method ; bloc variable is declared above
BlocBuilder<ChadsVascBloc, ChadsVascState>(
builder: (BuildContext context, ChadsVascState state)
{
return Column(
children: [
// this works very well
ListTile(
title: Text("Switch : ageOver65 is ${state.ageOver65.toString()}"),
trailing: Switch.adaptive(
value: state.ageOver65,
onChanged: (value) => bloc.add(AgeOver65Toggled(ageOver65: value))
)
),
// this is does not
SwitchTile(
// the change is well triggered in the title property !!!
title: "SwitchTile : ageOver65 is ${state.ageOver65.toString()}",
value: state.ageOver65, // but this does not change the button's status
onChanged: (value) => bloc.add(AgeOver65Toggled(ageOver65: value))
)
]
);
}
),
SwitchTile(
title: AppLocalizations.of(context)!.ageOver65,
value: bloc.state.ageOver65,
onChanged: (value) => bloc.add(AgeOver65Toggled(ageOver65: value)),
)
When I push the last button, the first one work very well ("base" Switch widget) but the second one (custom SwitchTile widget) does not : the title changes but not the button's position.
What did I do wrong ?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
因此,基本上,您两次使用相同的事件,这就是为什么集团无法识别任何更改的原因,因为您添加了同一事件,即使它具有不同的值。
而且我认为您以错误的方式使用了集团。与提供商和GETX不同,Bloc的主要目标是与州交付背景。它从来没有打算将其中的某些物体保存这么长时间。
对于您的情况
我认为您正在尝试编辑某种对象。使用BLOC事件将相关对象传输到另一个屏幕中,在编辑屏幕中,BLOC将侦听状态并将其解析到分配给交换机的本地变量(使用blocconsumer,侦听器,侦听器以设置状态))
如果您想更改variabel的值,请努
So basically, you use the same event twice, that's why the bloc doesn't recognize any changes because you add the same event even it has the different value.
And i think you use the Bloc in the wrong way. Unlike provider and getx, main objective of Bloc is deliver the context with state. It was never meant to save some object inside it for so long.
For your case,
I assume you are trying to edit some kind of object. Use Bloc event to transfer the related object into another screen, in edit screen, Bloc will listen the state and parsing it to the local variabel that was assigned to the Switch (use BlocConsumer, listener to set state)
if u want to change the value of the variabel, go for it, and confirm it by some trigger like button then add another event to finish the edit
问题似乎是:如何正确更新自定义开关小部件?
这似乎不是关于集团的,因为当我这样做时:
如果触发状态变化,$ {state.ageover65.tostring()}会更改,而不是交换机的值。
The problem seems to be : how to update properly a custom Switch widget ?
It does not seem to be about Bloc, because when I do that :
If I trigger a state change, ${state.ageOver65.toString()} changes but not the value of the Switch.
解决:我的错误不是使用集团,而是状态管理结构不良。由于开关小部件不必管理自己的状态,因此我的自定义开关小部件不应尝试改变自己的状态。
因此,它可以是一个简单的无状态范围,但在parent statefulwidget中使用,或者 - 我的情况 - 在blocbuilder中。我终于使用一个简单的context.watch()作为自定义小部件的值。
Solved : my error was not using BLoC but with bad state management structure. As a Switch widget does not have to manage its own state, my custom Switch widget should not try to changes its own state.
So it can be a simple StatelessWidget but used inside a parent StatefulWidget, or - I my case - in a BlocBuilder. I finally use a simple context.watch() as the value of my custom widget.