我正在尝试使用网格视图或列表视图在Flutter中实现分页。
// final movieRepository = dependencyInjector.get<MovieRepository>();
MoviesRepository movieRepository;
/// BehaviorSubject<T> StreamController that captures the latest item that has been
/// added to the controller, and emits that as the first item to any new listener.
BehaviorSubject moviesEventController = BehaviorSubject<MoviesModel>();
ValueStream<MoviesModel> get moviesSubscription =>
moviesEventController.stream;
bool isLoading = false;
int _page = 1;
int _maxPage = 2;
PublishSubject<MoviesModel> nextPageController = PublishSubject();
Stream<MoviesModel> get nextPageSubscription => nextPageController.stream;
MoviesBloc({@required this.movieRepository}) {
movieRepository = MoviesRepositoryImpl(service: MovieService());
moviesEventController.onListen = () => _fetchMovies();
nextPageController.onListen = () => _getMoreMovies();
}
_fetchMovies() async {
MoviesBaseResponse response = await movieRepository.fetchMovies(_page);
if (response != null) {
MoviesModel model = MoviesModel(
page: response.page,
movies: _getMovieList(response.movies),
);
moviesEventController.sink.add(model);
}
}
_getMoreMovies() async {
if(_page < _maxPage) {
_page++;
isLoading = true;
MoviesBaseResponse response = await movieRepository.fetchMovies(_page);
isLoading = false;
if(response != null) {
_maxPage = response.totalPages;
nextPageController.sink.add(_createMoviesModel(response));
}
}
}
List<MovieModel> _getMovieList(List<MovieResponse> response) {
List<MovieModel> modelList = [];
response.forEach((movie) {
MovieModel model = MovieModel(
video: movie.video,
posterPath: posterEndpoint + movie.posterPath,
movieId: movie.id,
adult: movie.adult,
backdropPath: backdropEndpoint + movie.backdropPath,
title: movie.title ?? movie.originalTitle,
overview: movie.overview,
releaseDate: movie.releaseDate,
);
modelList.add(model);
});
return modelList;
}
MoviesModel _createMoviesModel(MoviesBaseResponse response) {
return MoviesModel(
page: response.page,
totalPages: response.totalPages,
totalResult: response.totalResults,
movies: _getMovieList(response.movies)
);
}
}
在小部件中:
if (notification is ScrollEndNotification) {
SchedulerBinding.instance
.addPostFrameCallback((_) => bloc.nextPageController);
final before = notification.metrics.extentBefore;
final max = notification.metrics.maxScrollExtent;
if (before == max) {
bloc.nextPageSubscription;
}
}
return false;
}
onNotification
在StreamBuilder中的调用方式为:
return StreamBuilder<MoviesModel>(
stream: bloc.moviesSubscription,
builder: (context, snapshot) {
if (snapshot.hasData) {
return NotificationListener<ScrollNotification>(
onNotification: (notification) => onNotification(notification, bloc),
child: _gridViewBuilder(context, snapshot.data)
);
} else if (snapshot.hasError) {
return ErrorMessage(
message: CommonStrings().genericErrorMessage,
);
}
return Center(child: LoadingWidget());
},
);
}
所以现在,分页似乎不起作用。它不会在滚动条上加载第二页。让我知道我可能会想念的东西。预先感谢。