【问题标题】:How to use Provider for a Switch widget如何将 Provider 用于 Switch 小部件
【发布时间】:2021-01-26 22:50:31
【问题描述】:

从示例和在线看到的示例来看,通过使用 Provider,我们可以避免使用 Stateful Widgets 进行 Switch() 切换。我可以通过使用有状态小部件来实现这一点,方法是拥有一个可以通过 setState() 设置的全局变量。

一个例子:https://www.tutorialkart.com/flutter/flutter-switch/

但是我可以使用 Provider for a 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
),

Provider 使用的数据类。

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

请指教。谢谢。

【问题讨论】:

  • 究竟是什么错误?好像没问题?你能详细说明问题吗?
  • @sameerkashyap 我期待开关在 ON 和 OFF 之间切换。但是,当我单击 Switch 时,它只会保持打开状态。

标签: flutter dart


【解决方案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&lt;Data&gt;(context, listen: false) 读取数据时,例如在回调中。
  • Provider.of&lt;Data&gt;(context) 当您的小部件需要通过监听更改来重建时使用它

【讨论】:

  • 工作,谢谢。对于任何提到这个的人,还要注意使用 !isNoti 时会出错。那将永远是错误的。应该传入我的 Data 类的 isNotifiable 值的倒数。
  • 哦,是的,onChanged 已经提供了您不必反转的值。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-12-09
  • 2022-07-19
  • 1970-01-01
  • 1970-01-01
  • 2020-01-01
  • 2020-11-04
相关资源
最近更新 更多