您好,我正在尝试使用集团模式创建可由TextField
过滤的列表视图
这是我的代码
bloc:
class HomeBloc extends Bloc<HomeEvent, HomeState> {
List<Book> displayList = [];
....
@override
HomeState get initialState => UnfilteredState();
@override
Stream<HomeState> mapEventToState(
HomeEvent event,
) async* {
....
//handle filter by input
if(event is FilterListByTextEvent) {
displayList = displayList.where((book){
return book.title.toLowerCase().contains(event.filterString.toLowerCase());
}).toList();
yield FilteredState();
}
}
}
视图
class BookList extends StatelessWidget {
@override
Widget build(BuildContext context) {
return BlocBuilder<HomeBloc, HomeState>(
builder: (context, state) {
final HomeBloc bloc = Provider.of<HomeBloc>(context);
print(bloc.displayList);
return ListView.builder(
shrinkWrap: true,
itemCount: bloc.displayList.length,
itemBuilder: (context, index) {
return Dismissible(
key: UniqueKey(),
background: Container(
color: selectedColor,
),
child: Container(
height: 120,
padding: const EdgeInsets.fromLTRB(20, 4, 20, 4),
child: BookCard(
book: bloc.displayList[index],
),
),
onDismissed: (DismissDirection direction) {
},
);
},
);
},
);
}
}
我已经阅读了有关块模式和列表视图的其他讨论,但是我在这里面临的问题有所不同。
每次调用Filter事件时,bloc都会正确生成一个新的displayList
,但是,当BlocBuilder
重建我的UI时,listview不会正确更新。
呈现新的过滤列表,但旧结果不会消失。看来新清单只是堆叠在旧清单之上。
为了了解发生了什么,我尝试在调用build方法之前在BlocBuilder中打印必须呈现的列表。
打印结果正确。在控制台中,我只能看到新过滤的元素,而在用户界面中,我可以看到新的和旧的元素,一个又一个。
我在这里想念什么?
谢谢
答案 0 :(得分:1)
在displayList之前为加载和收益设置新状态。
if(event is FilterListByTextEvent) {
yield LoadFilterList();
displayList = displayList.where((book)
{
return
book.title.toLowerCase().contains(event.filterString.toLowerCase());
}).toList();
yield FilteredState();
}
答案 1 :(得分:0)
保留一个中间事件,例如一个ListInit,您将为其显示CircularProgressIndicator。除非您再次对其进行更新,否则BlocBuilder将停留在先前的状态。
因此在您的集团中,首先产生ListInit状态,然后执行过滤操作,然后产生FilteredState。