flutter_bloc 的 BlocBuilder 能否避免重建 Widget 的未更改部分?

Posted

技术标签:

【中文标题】flutter_bloc 的 BlocBuilder 能否避免重建 Widget 的未更改部分?【英文标题】:Can BlocBuilder of flutter_bloc avoid rebuild part of Widget which not changing? 【发布时间】:2019-11-23 06:43:33 【问题描述】:

flutter_blocBlocBuilder 是将页面的所有状态放在一起。

pulling a list 有一个案例,有 2 个数据(isPullingStatedataList),当dataList 不变时,如何避免构建 dataList 的小部件部分,但构建 isPullingState 的小部件部分从truefalse ?

BlocBuilderCondition 看起来只有在孔状态不变时才避免重建。

【问题讨论】:

【参考方案1】:

BlocBuilder 有一个可选参数condition,其类型为bool Function(State previous, State current),如果你想要小部件调用builder 函数,你需要返回true,如果你不想调用false .该参数可选,默认为true

因为在condition 参数中您有previous 状态和current 状态,您可以比较这些状态的属性,如果满足您的比较则返回true

请记住,您需要覆盖您的状态以及在您的状态类中使用的所有类的 == 运算符和 hashCode。简单的方法是使用equatable。

在您的情况下,您需要有这样的State

class MyState extends Equatable 
  final bool isPullingState;
  final List<MyClass> dataList;

  MyState(this.isPullingState, this.dataList)
      : super([isPullingState, dataList]);


class MyClass extends Equatable 
  final int property1;
  final int property2;

  MyClass(this.property1, this.property2)
      : super([
          property1,
          property2,
        ]);


然后在你的小部件中你可以设置你想要的条件:

@override
  Widget build(BuildContext context) 
    return Column(
      children: <Widget>[
        BlocBuilder(
          bloc: myBloc,
          condition: (MyState previous, MyState current) =>
              previous.isPullingState != current.isPullingState,
          builder: (BuildContext context, MyState state) 
            // this function is only called when isPullingState change
            return MyIsPullingWidget();
          ,
        ),
        BlocBuilder(
          bloc: myBloc,
          condition: (MyState previous, MyState current) =>
              previous.dataList != current.dataList,
          builder: (BuildContext context, MyState state) 
            // this function is only called when the dataList change
            return MyListWidget(state.dataList);
          ,
        ),
        BlocBuilder(
          bloc: myBloc,
          builder: (BuildContext context, MyState state) 
            // this function is called in each state change
            return MyListWidget(state.dataList);
          ,
        ),
      ],
    );
  

【讨论】:

以上是关于flutter_bloc 的 BlocBuilder 能否避免重建 Widget 的未更改部分?的主要内容,如果未能解决你的问题,请参考以下文章

由于某种原因不能使用flutter_bloc

flutter_bloc/provider RepositoryProvider vs Provider

从 v7.2.1 迁移到 flutter_bloc v 8.0.0 后不会触发 flutter_bloc 事件

使用带有flutter_bloc的Equatable类

Flutter_bloc 从没有 UI 事件的 firestore 获取更新的数据

改变flutter_bloc中的`currentState`属性