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_bloc
的BlocBuilder
是将页面的所有状态放在一起。
pulling a list
有一个案例,有 2 个数据(isPullingState
,dataList
),当dataList
不变时,如何避免构建 dataList 的小部件部分,但构建 isPullingState
的小部件部分从true 到 false ?
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/provider RepositoryProvider vs Provider
从 v7.2.1 迁移到 flutter_bloc v 8.0.0 后不会触发 flutter_bloc 事件