首页 > 解决方案 > Flutter中带有bloc的无限列表(表示层中的列表长度不变)

问题描述

我正在尝试从 api 加载数据,并且我正在使用 bloc 模式进行状态管理,但是当我在滚动表示层时调用 load more 时,只有当 hasReachedMax 参数为 true 时才会更改,如果它为 false,ui 仍然带有加载指示器

这是表示层

              Flexible(
              child: Container(
                child: BlocConsumer<AllProjectsBloc, AllProjectsState>(
                  builder: (context, state) {
                    if (state is AllProjectsLoadingState) {
                      return Center(
                        child: CircularProgressIndicator(),
                      );
                    } **else if (state is AllProjectsLoadedState) {
                      return ListView.builder(
                        controller: _scrollController,
                        itemCount: state.hasReachedMax ? state.allProjectsData.length  : 
                        state.allProjectsData.length +1 ,
                        itemBuilder: (context, int i) {
                          return i >= 5 ? BottomLoader() : UnitCard(
                            price: state.allProjectsData[i].price,
                            date: state.allProjectsData[i].title.en,
                            image: state.allProjectsData[i].image,
                            bathroom: state.allProjectsData[i].bathroom,
                            bedroom: state.allProjectsData[i].bedroom,
                            area: state.allProjectsData[i].area,**

                            function:(){
                              Navigator.push(context, MaterialPageRoute(builder: 
                             (context)=>DetailedProperty()));
                            });
                        },
                      );
                    } else if (state is FilteredProjectsLoadedState) {
                      return Expanded(
                          child: ListView.builder(
                            itemCount: state.filteredProjectsData.length,
                            itemBuilder: (context, i) {
                              return UnitCard(
                                price: 50,
                                date: '20/5/2020',
                                bedroom: 3,
                                bathroom: 2,
                                area: 120,
                                image: 
                  
                  
             'https://www.propertyturkey.com/uploads/realestate/larg/buyukcekmece_villa_1_8.jpg',
                                function:(){
                                  Navigator.push(context, MaterialPageRoute(builder: 
                     (context)=>DetailedProperty()));
                                } ,
                              );
                            },
                          ));
                    } else if (state is AllProjectsError) {
                      return ErrorView(
                          errorMessage: state.error.errorMessage,
                          retryAction: () {
                            BlocProvider.of<AllProjectsBloc>(context)
                                .add(state.failedEvent);
                          });
                    }
                    return Container();
                  },
                 
      }

集团阶级

     class AllProjectsBloc extends Bloc<AllProjectsEvents, AllProjectsState> {
        List<Data> propertyList = List();

           AllProjectsBloc() : super(AllProjectsInitialState());

         bool _hasReachedMax(AllProjectsState state) =>
            state is AllProjectsLoadedState && state.hasReachedMax;

         @override
        Stream<AllProjectsState> mapEventToState(AllProjectsEvents event) async* {
           bool isUserConnected = await NetworkUtilities.isConnected();
            if (isUserConnected == false) {
                yield AllProjectsError(
              failedEvent: event, error: Constants.CONNECTION_TIMEOUT);
                return;
             }
           if (event is FetchAllProjectsData && !_hasReachedMax(state)) {
               yield* _handleFetchingAllProject(event);
                      }

                  if (event is FetchFilteredProjectsData) {
          yield* _handleFetchingFilteredProject(event);
            return;
          }
            }

         Stream<AllProjectsState> _handleFetchingAllProject(
       FetchAllProjectsData event) async* {
       if (state is AllProjectsInitialState) {
  yield AllProjectsLoadingState();
  ResponseViewModel<List<Data>> handleProjectsFetchingResponse =
      await Repository.getAllPropertiesData(1);

  propertyList = handleProjectsFetchingResponse.responseData;
  print(propertyList.length);
  if (handleProjectsFetchingResponse.isSuccess) {
    yield AllProjectsLoadedState(
      allProjectsData: propertyList,
      hasReachedMax: false,
    );
  }
}
if (state is AllProjectsLoadedState) {
  ResponseViewModel<List<Data>> handleProjectsFetchingMoreResponse =
      await Repository.getAllPropertiesData(2);
  List<Data> tempList = handleProjectsFetchingMoreResponse.responseData;
  propertyList.addAll(tempList);

  if (handleProjectsFetchingMoreResponse.isSuccess) {
    yield AllProjectsLoadedState(
        allProjectsData: propertyList, hasReachedMax: true);
    print(propertyList.length);
  }
}
return;
   }

状态类

                     class AllProjectsLoadedState extends AllProjectsState {

                final  List<Data>  allProjectsData;
                 final bool hasReachedMax ;

             AllProjectsLoadedState({this.allProjectsData , this.hasReachedMax}) : 
       super([allProjectsData , hasReachedMax]);

           AllProjectsLoadedState copyWith ({List<Data> allProjectsData , bool hasReachedMax }){
      return AllProjectsLoadedState(
        allProjectsData: allProjectsData ?? this.allProjectsData ,
        hasReachedMax:hasReachedMax ?? this.hasReachedMax
           );
    }

    }

标签: flutterdartinfinite-scrollbloc

解决方案


问题是我产生了相同的状态,并且我正在使用 equatable 所以集团消费者无法识别状态的变化..解决方案是在产生 LoadedState 之前产生加载状态。


推荐阅读