为什么这个 BlocBuilder 在第二次触发后不重建我的列表?

Why this BlocBuilder do not rebuild my list after second trigger?

我有 cubit,我可以在其中下载电影并将其传递给列表:

class MovieSearchCubit extends Cubit<MovieState> {
  MovieSearchRepoInterface movieSearchRepository;
  List<Movie> emptyList = [];

  MovieSearchCubit({required this.movieSearchRepository})
      : super(const MovieState());

  Future<void> fetchMovies(String movieName) async {

    if (state.status != MovieStatus.failure) {
      final movies = await movieSearchRepository.searchMovies(movieName);

      if (movies.isRight()) {
    

        emit(state.copyWith(
            status: MovieStatus.success,
            posts: List.of(state.movies)
              ..addAll(
                movies.getOrElse((l) => emptyList),
              )));
      } else {
        emit(state.copyWith(status: MovieStatus.failure));
      }
    }
  }
}

我在 BlocBuilder 中这样调用它:

    BlocBuilder<MovieSearchCubit, MovieState>(
                    builder: (context, state) {
                  switch (state.status) {
                    case MovieStatus.failure:
                      return const Center(child: Text('failed to fetch posts'));
                    case MovieStatus.success:
                      if (state.movies.isEmpty) {
                        return const Center(child: Text('no posts'));
                      }
                      return Expanded(
                        child: ListView.builder(
                          shrinkWrap: true,
                          itemBuilder: (BuildContext context, int index) {
                            return index >= state.movies.length
                                ? BottomLoader()
                                : MovieCard(
                                    });
                          },
                          itemCount: state.movies.length,
                        ),
                      );

                    default:
                      return Container();
                  }
                }),

我正在通过按下按钮触发 cubit 函数 fetchMovies:

IconButton(
                      icon: const Icon(Icons.search),
                      onPressed: () async {
                        await context.read<MovieSearchCubit>().fetchMovies(inputStr);
                      },
                    ),

但是列表只是第一次构建,数据收集正确,问题在于显示。感谢您的任何提示。

稍后添加:这里看起来像 MovieState

 class MovieState extends Equatable {
  const MovieState({
    this.status = MovieStatus.initial,
    this.movies = const <Movie>[],
  });

  final MovieStatus status;
  final List<Movie> movies;

  MovieState copyWith({
    MovieStatus? status,
    List<Movie>? posts,
  }) {
    return MovieState(
      status: status ?? this.status,
      movies: posts ?? this.movies,
    );
  }

  @override
  List<Object?> get props => [];
}

BLoC 新状态仅在 oldState != newState 时发出,这意味着我们需要一种方法来正确区分状态的两个实例,我们这里有两种方法,或者通过覆盖状态的等号运算符,或者像您的情况一样,我们可以使用 Equatable 来轻松检查是否相等。

class MovieState extends Equatable {
  const MovieState({
    this.status = MovieStatus.initial,
    this.movies = const <Movie>[],
  });

  final MovieStatus status;
  final List<Movie> movies;

  MovieState copyWith({
    MovieStatus? status,
    List<Movie>? posts,
  }) {
    return MovieState(
      status: status ?? this.status,
      movies: posts ?? this.movies,
    );
  }

  @override
  List<Object?> get props => []; <--- Missing props
}

但是您的 class 缺少道具,因此 MovieState 的任何实例都是相等的!并且状态只会发出一次,这里的简单解决方法是将 属性 添加到您的道具方法中,以便进行适当的检查

  @override
  List<Object?> get props => [status, movies];