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

Posted

技术标签:

【中文标题】如何使用flutter bloc模式通过分页加载数据列表?【英文标题】:How do I use flutter bloc pattern to load list of data with paging? 【发布时间】:2019-12-10 17:23:16 【问题描述】:

我在我的应用程序中使用了flutter_bloc,并引用了这个sample。现在,当我运行我的应用程序时,它给了我一个错误提示:

flutter:类型“MovieUninitialized”不是类型的子类型 类型转换中的“MovieLoaded”

我的 bloc 包含三个文件:movie_state、movie_event 和 movie_bloc

movie_state.dart

import 'package:equatable/equatable.dart';
import 'package:movie_project/models/movie.dart';

abstract class MovieState extends Equatable 
  MovieState([List props = const []]) : super(props);


class MovieUninitialized extends MovieState 
  @override
  String toString() => 'MovieUninitialized';


class MovieError extends MovieState 
  @override
  String toString() => 'MovieError';


class MovieLoaded extends MovieState 
  final List<Movie> movies;
  final bool hasReachedMax;
  // Keeps track of the page to fetch the latest movies from the api
  final latestMoviesPage;

  MovieLoaded(
    this.movies,
    this.hasReachedMax,
    this.latestMoviesPage,
  ) : super([movies, hasReachedMax, latestMoviesPage]);

  MovieLoaded copyWith(
    List<Movie> movies,
    bool hasReachedMax,
    int latestMoviesPage,
  ) 
    return MovieLoaded(
      movies: movies ?? this.movies,
      hasReachedMax: hasReachedMax ?? this.hasReachedMax,
      latestMoviesPage: this.latestMoviesPage,
    );
  

  @override
  String toString() =>
      'PostLoaded  posts: $movies.length, hasReachedMax: $hasReachedMax ';

movie_event.dart

import 'package:equatable/equatable.dart';

abstract class MovieEvent extends Equatable 

class Fetch extends MovieEvent 
  @override
  String toString() => 'Fetch';

movie_bloc.dart

class MovieBloc extends Bloc<MovieEvent, MovieState> 
  final MovieRepository movieRepository;

  MovieBloc(@required this.movieRepository);

  @override
  Stream<MovieState> transform(
    Stream<MovieEvent> events,
    Stream<MovieState> Function(MovieEvent event) next,
  ) 
    return super.transform(
      (events as Observable<MovieEvent>).debounceTime(
        Duration(milliseconds: 500),
      ),
      next,
    );
  

  @override
  MovieState get initialState => MovieUninitialized();

  @override
  Stream<MovieState> mapEventToState(MovieEvent event) async* 
    if (event is Fetch && !_hasReachedMax(currentState)) 
      try 
        if (currentState is MovieUninitialized) 
          final movies = await movieRepository.fetchMovies(1);
          yield MovieLoaded(
            movies: movies,
            hasReachedMax: false,
            latestMoviesPage:
                (currentState as MovieLoaded).latestMoviesPage + 1,
          );
          return;
        
        if (currentState is MovieLoaded) 
          final movies = await movieRepository
              .fetchMovies((currentState as MovieLoaded).latestMoviesPage);
          yield movies.isEmpty
              ? (currentState as MovieLoaded).copyWith(hasReachedMax: true)
              : MovieLoaded(
                  movies: (currentState as MovieLoaded).movies + movies,
                  hasReachedMax: false,
                  latestMoviesPage:
                      (currentState as MovieLoaded).latestMoviesPage + 1,
                );
        
       catch (_) 
        print(_);
        yield MovieError();
      
    
  

  bool _hasReachedMax(MovieState state) =>
      state is MovieLoaded && state.hasReachedMax;

我需要增加 latestMoviesPage 直到达到最大限制。如果我从我的 bloc 代码中删除 latestMoviesPage 问题得到解决,但我真的需要它来加载更多页面。

【问题讨论】:

【参考方案1】:

代替

latestMoviesPage: (currentState as MovieLoaded).latestMoviesPage + 1,

我需要写:

latestMoviesPage: 2,

【讨论】:

以上是关于如何使用flutter bloc模式通过分页加载数据列表?的主要内容,如果未能解决你的问题,请参考以下文章

使用 Flutter BLoC 模式跟踪多个状态

在加载 Firebase 快照时使用 Flutter 中的 Bloc 流式等待和阻止其他事件

如何在 Flutter 上实现 BLoC 模式的 TDD

如何监听状态属性变化 Flutter bloc 模式

Dart/Flutter 中 BLoC 模式的最佳实践

flutter_bloc 4.0.0如何获取事件属性参数。