从示例和在线看到的示例来看,通过使用Provider,我们可以避免使用Stateful Widgets进行Switch()切换。我可以通过使用有状态的窗口小部件来实现此目的,该窗口小部件具有可以通过setState()设置的全局变量。
一个例子:https://www.tutorialkart.com/flutter/flutter-switch/
但是我可以使用Provider for Switch Widget作为无状态窗口小部件来实现吗?
这是我的Switch小部件:
Switch(
inactiveTrackColor: Colors.greenAccent,
onChanged: (bool isNoti) {
Provider.of<Data>(context, listen: false).toggleNotification(isNotifiable: !isNoti);
print('Noti: $isNoti'); // always prints false
print('Noti: ${Provider.of<Data>(context, listen: false).isNotifiable}'); // always prints true
},
value: Provider.of<Data>(context, listen: false).isNotifiable, // value doesn't change thus no toggle
),
提供商使用的数据类。
class Data extends ChangeNotifier {
bool isNotifiable = false;
void toggleNotification({bool isNotifiable = true}) {
this.isNotifiable = isNotifiable;
notifyListeners();
}
}
只是为了完整显示它,我确实将其包装在ChangeNotifierProvider中。
class HomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return ChangeNotifierProvider<Data>(
create: (context) => Data(),
child: ListTile(
leading: Icon(Icons.notifications),
title: Text('Notifications'),
trailing: Switch(
inactiveTrackColor: Colors.greenAccent,
onChanged: (bool isNoti) {
Provider.of<Data>(context, listen: false).toggleNotification(isNotifiable: !isNoti);
print('Noti: $isNoti');
print('Noti Provider: ${Provider.of<Data>(context, listen: false).isNotifiable}');
},
value: Provider.of<Data>(context, listen: false).isNotifiable,
),
),
);
}
}
当我点击切换开关时,总是会得到以下输出。
Noti: false
Noti Provider: true
请咨询。谢谢。
答案 0 :(得分:1)
我认为我发现了您的错误,您所做的一切都正确,期望您的交换机不会重建,而这里的错误是您提到的,因此它不应重建。
trailing: Switch(
inactiveTrackColor: Colors.greenAccent,
onChanged: (bool isNoti) {
Provider.of<Data>(context, listen: false).toggleNotification(isNotifiable: !isNoti);
print('Noti: $isNoti');
print('Noti Provider: ${Provider.of<Data>(context, listen: false).isNotifiable}');
},
value: Provider.of<Data>(context).isNotifiable, // remove `listen: false`
),
因为价值是您的交换机重建所依赖的。但是提供者没有听更改,因为您提到了listen: false
。
使用
Provider.of<Data>(context, listen: false)
,当您在读取诸如回调中的数据时。Provider.of<Data>(context)
在您的小部件需要通过侦听更改来重建时使用它