【问题标题】:Change state in one Widget from another widget从另一个小部件更改一个小部件中的状态
【发布时间】:2019-12-17 06:26:01
【问题描述】:

我正在编写一个 Flutter 应用程序,其中向用户展示了一个 PageView 小部件,该小部件允许他/她通过滑动在 3 个“页面”之间导航。

我遵循https://medium.com/flutter-community/flutter-app-architecture-101-vanilla-scoped-model-bloc-7eff7b2baf7e 中使用的设置,我使用单个类将数据加载到我的模型中,这应该反映相应的状态变化 (IsLoadingData/HasData)。

我有一个包含所有 ViewPage 小部件的主页。页面是在 MainPageState 对象中构造的,如下所示:

  @override
  void initState() {
    _setBloc = SetBloc(widget._repository);
    _notificationBloc = NotificationBloc(widget._repository);
    leftWidget = NotificationPage(_notificationBloc);
    middleWidget = SetPage(_setBloc);
    currentPage = middleWidget;
    super.initState();
  } 

如果我们进入 NotificationPage,那么它做的第一件事就是尝试加载数据:

      NotificationPage(this._notificationBloc) {
        _notificationBloc.loadNotificationData();
      }

which should be reflected in the build function when a user directs the application to it:

  //TODO: Consider if state management is correct
  @override
  Widget build(BuildContext context) {
    return StreamBuilder<NotificationState>(
      stream: _notificationBloc.notification.asBroadcastStream(),
      //initialData might be problematic
      initialData: NotificationLoadingState(),
      builder: (context, snapshot) {
        if (snapshot.data is NotificationLoadingState) {
          return _buildLoading();
        }
        if (snapshot.data is NotificationDataState) {
          NotificationDataState state = snapshot.data;
          return buildBody(context, state.notification);
        } else {
          return Container();
        }
      },
    );
  }

发生的情况是,即使在存储库中加载了数据,屏幕也会始终点击“NotificationLoadingState”:

  void loadNotificationData() {
    _setStreamController.sink.add(NotificationState._notificationLoading());
    _repository.getNotificationTime().then((notification) {
      _setStreamController.sink
          .add(NotificationState._notificationData(notification));
      print(notification);
    });
  }

通知是在另一个不是通知页面的页面上打印的。

我做错了什么?

【问题讨论】:

    标签: flutter stream bloc


    【解决方案1】:
    //....
    
    class _SomeState extends State<SomeWidget> {
    
     //....
     Stream<int> notificationStream;
     //....
    
     @override
      void initState() {
       //....
        notificationStream = _notificationBloc.notification.asBroadcastStream()
        super.initState();
      } 
    
        //....
       Widget build(BuildContext context) {
        return StreamBuilder<NotificationState>(
          stream: notificationStream,
         //....    
    

    将您的 Stream 保存在某处并停止每次初始化它。 我怀疑 build 方法被多次调用,因此您创建了一个新流(initState 被调用一次)。

    如果这有帮助,请尝试告诉我。

    【讨论】:

    • 我正在调查这些问题,因为我认为您在创建多个流这一事实上是正确的,但我似乎无法让它正常工作。例如,如果我在主页中检查通知页面的状态,则主页会回答有数据。然而,通知页面将继续加载,就好像它没有数据一样。
    猜你喜欢
    • 2021-07-20
    • 1970-01-01
    • 1970-01-01
    • 2021-12-26
    • 2021-09-11
    • 1970-01-01
    • 2021-01-01
    • 1970-01-01
    • 2021-12-26
    相关资源
    最近更新 更多