繁体   English   中英

Flutter Bloc 状态管理

[英]Flutter Bloc state management

我正在尝试构建基于 Flutter 的平板电脑应用程序。 因为平板电脑上有更多的屏幕空间,所以每个页面都由一组小部件组成,每个小部件都使用自己的 bloc 实现构建。

我对 flutter 和 bloc 还很陌生,当前的设计只是为每个改变小部件树生成方式的状态变化重新生成小部件树。 也许我不明白,更可能是真的,当状态发生变化时,bloc builder 将返回一个小部件。 我还没有看到保存页面小部件并且新状态只是修改保存的小部件的示例。

这是我遇到的问题的示例。 我正在使用块观察器来监视块的状态。

当前的小部件树看起来像:

LocaleTile [LocaleTileBloc, LocaleTileInit] 
    NeighborColumn [NeighborBloc, NeighborInit] 
    LocaleColumn [RegionBloc, RegionInit] 
    FamilyColumn [FamilyBloc, FamilyInit] 

NewLocaleEvent 的事件到状态映射如下所示:

Stream<LocaleTileState> _mapNewLocaleToState(NewLocaleEvent event) async* {
    yield LocaleTileLaughing();
    yield NewLocaleState(event.locale);
  }

当用户按下区域设置按钮时,我向 LocaleTileBloc -> NewLocaleEvent 发送一个事件。 观察者日志是:

// Create NewLocaleEvent
: onEvent -- b: LocaleTileBloc, e: NewLocaleEvent: {Bellevue}

// Consume the NewLocaleEvent
: onTrans -- b: LocaleTileBloc, t: Transition { currentState: LocaleTileInit, 
                                                event: NewLocaleEvent: {Bellevue}, 
                                                nextState: NewLocalState: {Bellevue} }
: onChange -- c: LocaleTileBloc, c: Change { currentState: LocaleTileInit, 
                                             nextState: NewLocalState: {Bellevue} }
// The widget that implements the LocalTileBloc receives the new state
: RegionLocalTile[LocaleTileBloc] State: NewLocalState: {Bellevue}

如果用户按下新的区域设置来显示它,我会在观察者日志中得到以下信息:

// Create NewLocaleEvent Kirkland
: onEvent -- b: LocaleTileBloc, e: NewLocaleEvent: {Kirkland}

// Consume NewLocalState
// Where did this come from
: RegionLocalTile[LocaleTileBloc] State: NewLocalState: {Bellevue}

当页面小部件重新生成时,似乎 bloc 告诉新的 RegionLocalTile 小部件它必须返回到旧状态,因此应用程序执行所有 api 调用以重新生成页面,然后:

: onTrans -- b: LocaleTileBloc, t: Transition { currentState: NewLocalState: {Bellevue}, 
                                                event: NewLocaleEvent: {Kirkland}, 
                                                nextState: LocaleTileLaughing }
: onChange -- c: LocaleTileBloc, c: Change { currentState: NewLocalState: {Bellevue}, 
                                             nextState: LocaleTileLaughing }

: onTrans -- b: LocaleTileBloc, t: Transition { currentState: LocaleTileLaughing, 
                                                event: NewLocaleEvent: {Kirkland}, 
                                                nextState: NewLocalState: {Kirkland} }
: onChange -- c: LocaleTileBloc, c: Change { currentState: LocaleTileLaughing, 
                                             nextState: NewLocalState: {Kirkland} }
: RegionLocalTile[LocaleTileBloc] State: NewLocalState: {Kirkland}

然后小部件页面获得正确的状态。

我想我的问题是:当实现 bloc 的小部件响应状态更改时,它必须返回一个小部件。 有两种选择,要么重新生成小部件,要么将其保存在有状态的小部件中,然后创建键来修改特定的子小部件。

如果我在每次状态变化时重新生成它,那么每次小部件出现时,它都会被提醒它的旧状态,并且必须重做它刚刚离开的所有工作。 我希望我可以重置集团以回到初始状态。

我决定解决这个问题的方法是保存通过的小部件,那些不会根据状态变化而改变 ui 的小部件,然后将它们重新插入小部件树中。 改变 ui 的小部件会生成新的小部件,并将新部件插入到树中。 此更改节省了多个重复的 api 调用,因为 bloc 不必告诉小部件将其状态重置为最后一个状态,然后转到新状态:

通常,父级的状态如下所示:

class _RegionState extends State<RegionPage> {

    LocaleTile localeTile;

    @override
    void initState() {
      super.initState();
      localeTile = null;
    }

    Widget getWidget(BlocState state) {
      if (localeTile == null) {
        localeTile = new LocaleTile(state);
      }
      return Center( child: localeTile);
    }

    @override
    Widget build(BuildContext context) {
      return BlocBuilder<EntityBloc, EntityState>(builder: (context, state) {
          if (state is EntityLoaded) {
            ...
            // computeSomething();
            // Send events to the localTileBloc
          }
          return getWidget(state);
      });
    }

    

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM