Flutter中带有bloc的无限列表(表示层中的列表长度不变)

Posted

技术标签:

【中文标题】Flutter中带有bloc的无限列表(表示层中的列表长度不变)【英文标题】:Infinite List with bloc (List length not changing in the presentation layer) in Flutter 【发布时间】:2020-11-29 20:39:28 【问题描述】:

我正在尝试从 api 加载数据,并且我正在使用 bloc 模式进行状态管理,但是当我调用 滚动表示层时加载更多仅当 hasReachedMax 参数为 true 时才会更改 如果它是假的,那么 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
           );
    

    

【问题讨论】:

【参考方案1】:

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

【讨论】:

以上是关于Flutter中带有bloc的无限列表(表示层中的列表长度不变)的主要内容,如果未能解决你的问题,请参考以下文章

Flutter - 转换颤振 bloc 事件以添加去抖动

改变flutter_bloc中的`currentState`属性

如何使用 bloc flutter 更改单个列表项的状态?

从非小部件类访问 Flutter Bloc

如何使用flutter bloc模式通过分页加载数据列表?

Flutter中带有whereIn条件的过滤器列表?