【问题标题】:Consumer Provider doesn't seem to notify listeners?消费者提供者似乎没有通知听众?
【发布时间】:2021-08-31 14:05:22
【问题描述】:

下面的最小可重现代码旨在在按下按钮时有一个加载图标(模拟发生异步计算时的加载)。

由于某种原因,Consumer Provider 在回调期间不会重建小部件。


我的看法:

class HomeView extends StatefulWidget {

  const HomeView();

  @override
  _HomeViewState createState() => _HomeViewState();
}

class _HomeViewState extends State<HomeView> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: ChangeNotifierProvider(
        create: (_) => HomeViewModel(99),
        child: Consumer<HomeViewModel>(
          builder: (_, myModel, __) => Center(
            child: ButtonsAtBottom(
              addEventAction: () => myModel.increment(context),
              busy: myModel.busy
            ),
          ),
        ),
      ),
    );
  }
}

我模拟做业务逻辑的模型:

class HomeViewModel extends LoadableModel {
  late int integer;
  HomeViewModel(this.integer);
  
  void increment(BuildContext context) {
    super.setBusy(true);
    Future.delayed(Duration(seconds: 3), () => print(integer++));
    super.setBusy(false);
    //Passed in context just to try to simulate my real app
    //print(context);
  }
}

class LoadableModel extends ChangeNotifier {
  bool _busy = false;
  bool get busy => _busy;

  void setBusy(bool value) {
    _busy = value;
    notifyListeners();
  }
}

问题:当回调执行时,其中的setBusy() 方法被执行,它们应该通知监听器并更新其中传递的busy 字段。随后,应显示文本或加载程序。

但是,busy 字段永远不会更新并保持为false

class ButtonsAtBottom extends StatelessWidget {
  final bool busy;
  final void Function() addEventAction;
  const ButtonsAtBottom({required this.busy, required this.addEventAction});

  @override
  Widget build(BuildContext context) {
    print("busy value: $busy");
    return Row(
      mainAxisAlignment: MainAxisAlignment.spaceBetween,
      children: [
        IconButton(
          onPressed: () => Navigator.pop(context),
          icon: Icon(Icons.clear_rounded),
        ),
        ElevatedButton.icon(
            onPressed: addEventAction,
            icon: Icon(Icons.save_alt_rounded),
            label: busy
                ? CircularProgressIndicator.adaptive(
                    backgroundColor: Colors.white,
                  )
                : Text("Save")),
      ],
    );
  }
}

【问题讨论】:

  • 尝试在set busy setter 上更改setBusy 方法并在您的increment 方法中设置值。

标签: flutter dart flutter-provider


【解决方案1】:

您是否尝试过等待未来? ?

【讨论】:

  • 哦,对了,这个虚拟示例有效,但我的实际应用程序没有(我打印了 boolean 之前和之后的值,它们是相同的)。但是,我确实找到了一种解决方法,将“await asynchronous computation”替换为“Future.delayed(Duration(seconds:2),await asynchronous computation”。
  • 更新:我没有使用 await 作为内部方法,它也恰好是异步的!将 await 放在那里有效!
  • 不错! :D 乐于帮助 o/
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-03-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多