Flutter 如何对bloc模式使用无限滚动分页

Flutter 如何对bloc模式使用无限滚动分页,flutter,infinite-scroll,bloc,Flutter,Infinite Scroll,Bloc,我目前正在学习并将代码转换为BLoc模式。在我使用Future进行无限滚动之前,我不知道如何使用bloc或者它是否与bloc兼容 所以现在我在尝试,因为它在文档中说它支持Bloc。但我不理解docs for bloc中的示例代码。你能给我一个简单的例子,如何使用它与集团?我当前使用的是颤振块:^6.1.3 以下是我的集团脚本: class TimeslotViewBloc extends Bloc<TimeslotViewEvent, TimeslotViewState> { f

我目前正在学习并将代码转换为BLoc模式。在我使用
Future
进行无限滚动之前,我不知道如何使用bloc或者它是否与bloc兼容

所以现在我在尝试,因为它在文档中说它支持Bloc。但我不理解docs for bloc中的示例代码。你能给我一个简单的例子,如何使用它与集团?我当前使用的是颤振块:^6.1.3

以下是我的集团脚本:

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];
}
class TimeslotViewBloc扩展了Bloc{
最终GetTimeslotView GetTimeslotView;
TimeslotViewBloc({this.gettimeslotView}):超级(TimeslotViewInitialState());
@凌驾
流映射事件状态(
TimeslotViewEvent事件,
)异步*{
if(事件为GetTimeslotViewEvent){
产生TimeslotViewLoadingState();
最终失败或成功=等待gettimeslotView(参数(
id:event.id,
日期:event.date,
));
收益率*\加载的错误状态(失败或成功);
}
}
流\u i已加载或错误状态(
无论是失败还是失败,
)异步*{
屈服失效或三角折叠(
(失败)=>TimeslotViewErrorState(
消息:_-mapFailureToMessage(failure),failure:failure),
(结果)=>TimeslotViewLoadedState(结果),
);
}
//集团事件----------------------------------------
抽象类TimeslotViewEvent扩展了Equatable{
const TimeslotViewEvent();
@凌驾
列表获取道具=>[];
}
类GetTimeslotViewEvent扩展了TimeslotViewEvent{
最终字符串id;
最终字符串日期;
最终整数偏移量;
最终整数限制;
GetTimeslotViewEvent(
{this.id,
这个日期,
这个,抵消,,
此参数为});
}
//集团国家----------------------------------------
抽象类TimeslotViewState扩展了Equatable{
常量TimeslotViewState();
@凌驾
列表获取道具=>[];
}
类TimeslotViewLoadingState扩展TimeslotViewState{}
类TimeslotViewLoadedState扩展了TimeslotViewState{
最后清单记录;
TimeslotViewLoadedState(this.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,
          ),
        ),
      ),),
      );
  }
@覆盖
小部件构建(构建上下文){
返回BlocProvider(
创建:(上下文)=>\u timeLotBloc,
孩子:布洛克斯腾纳(
侦听器:(上下文、状态){
if(状态为TimeslotViewLoadedState){
//保存记录计数而不是记录列表
totalRecordCount+=state.records.length;
最终_next=1+totalRecordCount;
最终isLastPage=state.records.length<页面大小;
如果(isLastPage){
_pagingController.appendLastPage(state.records);
}否则{
_pagingController.appendPage(state.records,_next);
}
}
if(状态为TimeslotViewErrorState){
_pagingController.error=state.error;
}
},
//已从bloc builder中删除pagedListview
子:PagedListView(
分页控制器:_分页控制器,
builderDelegate:PagedChildBuilderDelegate(
itemBuilder:(上下文、时间、索引)=>TimeslotViewEntityListItem(
人物:时间,
),
),
),),
);
}
类分页列表扩展StatefulWidget{
常量分页列表({Key?Key}):超级(Key:Key);
@凌驾
_PaginatedListState createState()=>_PaginatedListState();
}
类_PaginatedListState扩展状态{
//*假设您使用getIt和injectable
后期期末考试_timeLotBloc=getIt();
列出记录=[];
//*初始化页面控制器
最终分页控制器_分页控制器=
分页控制器(第一页键:0);
@凌驾
void initState(){
super.initState();
//*所以在活动中添加记录列表
_pagingController.addPageRequestListener(
(pageKey)=>\u timeLotBloc
.add(GetTimeslotViewEvent(记录:记录,偏移量:pageKey,限制:10)),
);
}
@凌驾
无效处置(){
super.dispose();
_timeLotBloc.close();
_pagingController.dispose();
}
@凌驾
小部件构建(构建上下文){
返回BlocProvider(
创建:(上下文)=>\u timeLotBloc,
孩子:布洛克斯腾纳(
侦听器:(上下文、状态){
if(状态为TimeslotViewLoadedState){
记录=state.records;
//忘记现有记录
//关于最后一页,从
//后端
int lastPage=state.lastPage
最终_next=1+记录长度;
如果(_next>lastPage){
_pagingController.appendLastPage(记录);
}
否则{
_pagingController.appendPage(记录,下一步);
}
}
if(状态为TimeslotViewErrorState){
_pagingController.error=state.error;
}
},孩子:BlocBuilder(
生成器:(上下文,状态)=>PagedListView(
分页控制器:_分页控制器,
builderDelegate:PagedChildBuilderDelegate(
itemBuilder:(上下文、时间、索引)=>TimeslotViewEntityListItem(
人物:时间,
),
),
),),
),
);
}
}
现在是bloc事件类

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,
  });
}
类GetTimeslotViewEvent扩展了TimeslotViewEvent{
最终字符串id;
最终字符串日期;
最终整数偏移量;
最终整数限制;
//将此添加到事件中
最后清单记录;
GetTimeslotViewEvent({
这个身份证,
这个日期,
这个,抵消,,
这个,限制,,
需要这项记录,
});
}
论国家级

class TimeslotViewLoadedState extends TimeslotViewState {
  final List<TimeslotViewEntity> records;
  final List<TimeslotViewEntity> existingRecords;
  TimeslotViewLoadedState(this.records, this.existingRecords);
  @override
  List<Object> get props => [records, existingRecords];
}
类TimeslotViewLoadedState扩展了TimeslotViewState{
最后清单记录;
现有记录的最终清单;
TimeslotViewLoadedState(this.records,this.existingRecords);
@凌驾
列表获取道具=>[记录,存在]
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),
    );
  }