如何将infinite_scroll_pagination 用于块模式
Posted
技术标签:
【中文标题】如何将infinite_scroll_pagination 用于块模式【英文标题】:how to use infinite_scroll_pagination for bloc pattern 【发布时间】:2021-08-22 06:24:28 【问题描述】:我目前正在学习并将我的代码转换为 BLoc 模式。在我使用flutter_pagewise ^1.2.3 进行无限滚动之前,我使用Future<>
,但我不知道如何使用 bloc 或者它是否与它兼容。
所以现在我正在尝试infinite_scroll_pagination: ^2.3.0,因为它在其文档中说它支持 Bloc。但我不理解 bloc 文档中的示例代码。你能给我一个简单的例子来说明如何将它与 bloc 一起使用吗?我目前正在使用flutter_bloc:^6.1.3。
这是我的 bloc 脚本:
class TimeslotViewBloc extends Bloc<TimeslotViewEvent, TimeslotViewState>
final GetTimeslotView gettimeslotView;
TimeslotViewBloc(this.gettimeslotView) : super(TimeslotViewInitialState());
@override
Stream<TimeslotViewState> mapEventToState(
TimeslotViewEvent event,
) async*
if (event is GetTimeslotViewEvent)
yield TimeslotViewLoadingState();
final failureOrSuccess = await gettimeslotView(Params(
id: event.id,
date: event.date,
));
yield* _eitherLoadedOrErrorState(failureOrSuccess);
Stream<TimeslotViewState> _eitherLoadedOrErrorState(
Either<Failure, List<TimeslotViewEntity>> failureOrTrivia,
) async*
yield failureOrTrivia.fold(
(failure) => TimeslotViewErrorState(
message: _mapFailureToMessage(failure), failure: failure),
(result) => TimeslotViewLoadedState(result),
);
//Bloc Events----------------------------------------
abstract class TimeslotViewEvent extends Equatable
const TimeslotViewEvent();
@override
List<Object> get props => [];
class GetTimeslotViewEvent extends TimeslotViewEvent
final String id;
final String date;
final int offset;
final int limit;
GetTimeslotViewEvent(
this.id,
this.date,
this.offset,
this.limit);
//Bloc States----------------------------------------
abstract class TimeslotViewState extends Equatable
const TimeslotViewState();
@override
List<Object> get props => [];
class TimeslotViewLoadingState extends TimeslotViewState
class TimeslotViewLoadedState extends TimeslotViewState
final List<TimeslotViewEntity> records;
TimeslotViewLoadedState(this.records);
@override
List<Object> get props => [records];
更新:这是适用于我的 Davii 修改后的代码
@override
Widget build(BuildContext context)
return BlocProvider(
create: (context) => _timeLotBloc,
child: BlocListener<TimeslotViewBloc, TimeslotViewState>(
listener: (context, state)
if (state is TimeslotViewLoadedState)
//Save record count instead of records list
totalRecordCount += state.records.length;
final _next = 1 + totalRecordCount;
final isLastPage = state.records.length < PAGE_SIZE;
if (isLastPage)
_pagingController.appendLastPage(state.records);
else
_pagingController.appendPage(state.records, _next);
if (state is TimeslotViewErrorState)
_pagingController.error = state.error;
,
//Removed pagedListview from bloc builder
child: PagedListView<int, TimeslotViewEntity>(
pagingController: _pagingController,
builderDelegate: PagedChildBuilderDelegate<TimeslotViewEntity>(
itemBuilder: (context, time, index) => TimeslotViewEntityListItem(
character: time,
),
),
),),
);
【问题讨论】:
我已经在我的一个原型项目中实现了无限滚动,没有任何包:github.com/mkobuolys/shopping-app-prototype 检查modules/products/bloc/products_bloc.dart
以获取 BLoC 示例,modules/products/widgets/products_list_view.dart
获取使用示例。如果您需要任何说明,请告诉我。
以防万一有人在使用flutter_bloc包,这里是官方教程:bloclibrary.dev/#/flutterinfinitelisttutorial
【参考方案1】:
class PaginatedList extends StatefulWidget
const PaginatedList(Key? key) : super(key: key);
@override
_PaginatedListState createState() => _PaginatedListState();
class _PaginatedListState extends State<PaginatedList>
//*bloc assuming you use getIt and injectable
late final _timeLotBloc = getIt<TimeslotViewBloc>();
List<TimeslotViewEntity> records = [];
//*initialize page controller
final PagingController<int, TimeslotViewEntity> _pagingController =
PagingController(firstPageKey: 0);
@override
void initState()
super.initState();
//*so at event add list of records
_pagingController.addPageRequestListener(
(pageKey) => _timeLotBloc
.add(GetTimeslotViewEvent(records: records, offset: pageKey,limit: 10)),
);
@override
void dispose()
super.dispose();
_timeLotBloc.close();
_pagingController.dispose();
@override
Widget build(BuildContext context)
return BlocProvider(
create: (context) => _timeLotBloc,
child: BlocListener<TimeslotViewBloc, TimeslotViewState>(
listener: (context, state)
if (state is TimeslotViewLoadedState)
records =state.records;
//forget about existing record
//about the last page, fetch last page number from
//backend
int lastPage = state.lastPage
final _next = 1 + records.length;
if(_next>lastPage)
_pagingController.appendLastPage(records);
else
_pagingController.appendPage(records, _next);
if (state is TimeslotViewErrorState)
_pagingController.error = state.error;
,child: BlocBuilder<TimeslotViewBloc,TimeslotViewState>(
builder: (context,state)=> PagedListView<int, TimeslotViewEntity>(
pagingController: _pagingController,
builderDelegate: PagedChildBuilderDelegate<TimeslotViewEntity>(
itemBuilder: (context, time, index) => TimeslotViewEntityListItem(
character: time,
),
),
),),
),
);
现在在集团事件类
class GetTimeslotViewEvent extends TimeslotViewEvent
final String id;
final String date;
final int offset;
final int limit;
//add this on event
final List<TimeslotViewEntity> records;
GetTimeslotViewEvent(
this.id,
this.date,
this.offset,
this.limit,
required this.records,
);
关于状态类
class TimeslotViewLoadedState extends TimeslotViewState
final List<TimeslotViewEntity> records;
final List<TimeslotViewEntity> existingRecords;
TimeslotViewLoadedState(this.records, this.existingRecords);
@override
List<Object> get props => [records, existingRecords];
现在就在集团内
yield* _eitherLoadedOrErrorState(failureOrSuccess,event);
Stream<TimeslotViewState> _eitherLoadedOrErrorState(
Either<Failure, List<TimeslotViewEntity>> failureOrTrivia,
GetTimeslotViewEvent event,
) async*
yield failureOrTrivia.fold(
(failure) => TimeslotViewErrorState(
message: _mapFailureToMessage(failure), failure: failure),
//existing records from the event,
(result) => TimeslotViewLoadedState(result,event.records),
);
这个方法对我有用
【讨论】:
感谢您的示例代码。我已经尝试过您的代码,但向下滚动时从 API 获取记录并没有停止。我已经编辑了PaginateList
页面,并从 bloc builder 中删除了 PageListView
。我还添加了addLastPage
,我认为这就是告诉它停止获取记录的原因?我还编辑了我的问题并包含了修改后的代码。
是的...我也注意到那里..所以你必须从后端获取最后一页..就像最后一个页码...以上是关于如何将infinite_scroll_pagination 用于块模式的主要内容,如果未能解决你的问题,请参考以下文章