Flutter Bloc分页工作正常,但整个ListView,生成器,而不是简单地追加新项

oalqel3c  于 2023-05-01  发布在  Flutter
关注(0)|答案(1)|浏览(123)

我对flutter_bloc比较陌生,所以如果这是一个简单的问题,请原谅我。我有一个ListView。一个从我的API中呈现列表的构建器,我的目标是对这个列表进行分页。我已经做到了这一点,但问题是,当我从我的块中向列表添加新项时,整个ListView会重新构建,页面会跳回到列表中的第一个项。
以下是我的BLOCK:我认为问题是我在最后再次发出“MemesBlocLoaded”状态?还是别的原因

final ApiRepository apiRepository;
  int page = 0;
  MemesBlocBloc(this.apiRepository) : super(MemesBlocInitial()) {
    on<GetMemesList>((event, emit) async {
      try {
        emit(MemesBlocLoading());
        List memesList = await apiRepository.fetchMemes(page);
        emit(MemesBlocLoaded(memesList));
        page++;
        on<GetMore>((event, emit) async {
          emit(const MemesBlocLoadingMore(true));
          List memesListMore = await apiRepository.fetchMemes(page);
          memesList.addAll(memesListMore);
          emit(const MemesBlocLoadingMore(false));
          emit(MemesBlocLoaded(memesList));
          page++;
        });
      } on NetworkError {
        emit(const MemesBlocError("Failed to fetch data."));
      }
    });
  }
}

使用构建方法编辑:

if (state is MemesBlocLoaded) {
                return SingleChildScrollView(
                  child: Column(
                    children: [
                      ListView.builder(
                          primary: false,
                          shrinkWrap: true,
                          itemCount: state.memes.length,
                          itemBuilder: (context, index) {
                            return Stack(
                              children: [
                                Padding(
                                  padding: const EdgeInsets.all(8.0),
                                  child: ClipRRect(
                                    borderRadius: BorderRadius.circular(8.0),
                                    child: Image.network(
                                      state.memes[index].url,
                                      width: double.infinity,
                                      height: 400,
                                      fit: BoxFit.cover,
                                    ),
                                  ),
                                ),
                                Positioned(
                                  right: 16,
                                  bottom: 16,
                                  child: Column(
                                    crossAxisAlignment: CrossAxisAlignment.end,
                                    children: [
                                      IconButton(
                                        onPressed: () {},
                                        icon: const Icon(Icons.arrow_upward),
                                        color: Colors.white,
                                      ),
                                      IconButton(
                                        onPressed: () {},
                                        icon: const Icon(Icons.arrow_downward),
                                        color: Colors.white,
                                      ),
                                      IconButton(
                                        onPressed: () {},
                                        icon: const Icon(Icons.comment),
                                        color: Colors.white,
                                      ),
                                      IconButton(
                                          onPressed: () {},
                                          icon: const Icon(
                                            Icons.save_alt_outlined,
                                            color: Colors.white,
                                          )),
                                      IconButton(
                                          onPressed: () {},
                                          icon: const Icon(
                                            Icons.share,
                                            color: Colors.white,
                                          )),
                                      IconButton(
                                        onPressed: () {},
                                        icon: const Icon(Icons.report_outlined),
                                        color: Colors.white,
                                      ),
                                      Padding(
                                        padding:
                                            const EdgeInsets.only(right: 4.0),
                                        child: GestureDetector(
                                            onTap: () {
                                              print('profile');
                                            },
                                            child: const CircleAvatar(
                                              radius: 16,
                                              backgroundImage: NetworkImage(
                                                  'https://images.unsplash.com/photo-1554151228-14d9def656e4?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=686&q=80'),
                                            )),
                                      )
                                    ],
                                  ),
                                )
                              ],
                            );
                          }),
                      state.memes.length >= 1
                          ? state is MemesBlocLoadingMore
                              ? const Center(
                                  child: CircularProgressIndicator(
                                      color: Colors.black),
                                )
                              : Padding(
                                  padding: const EdgeInsets.all(8.0),
                                  child: ElevatedButton(
                                      style: ElevatedButton.styleFrom(
                                          backgroundColor: Colors.white),
                                      onPressed: () async {
                                        context
                                            .read<MemesBlocBloc>()
                                            .add(GetMore());
                                      },
                                      child: const Text('View more',
                                          style:
                                              TextStyle(color: Colors.black))),
                                )
                          : const SizedBox()
                    ],
                  ),
                );
              }
6xfqseft

6xfqseft1#

我希望我没有迟到。您应该执行类似下面代码的操作
请检查具有相同功能https://github.com/IndrajeetS/flutter-animation的存储库

on<PostsLoadMoreEvent>((event, emit) async {
  if (scrollController.position.pixels ==
      scrollController.position.maxScrollExtent) {
    isLoadMore = true;
    page++;
    final newPosts = await _postRepository.fetchPosts(page);

    // ---------------------------------------------
    // Appending/Combining Old List with new list
    // ---------------------------------------------
    emit(PostsLoadedState(
      posts: [...state.posts, ...newPosts],
    ));
  }
});

相关问题