如何将Provider用于Switch小部件

时间:2020-10-12 15:41:29

标签: flutter dart

从示例和在线看到的示例来看,通过使用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

请咨询。谢谢。

1 个答案:

答案 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)在您的小部件需要通过侦听更改来重建时使用它