在使用flutter_bloc加载更多数据时发出另一种状态



如何实现加载更多的数据与flutter_bloc不重载每次:我有这个:

post_bloc.dart:

import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:scroool/post_events.dart';
import 'package:scroool/post_repo.dart';
import 'package:scroool/post_states.dart';
class PostsBloc extends Bloc<PostEvents, PostsStates> {
PostRepo repo;
int page = 1;
ScrollController controller = ScrollController();
PostsBloc(this.repo) : super(PostInitState()){
on<FetchPosts>((event, emit) async{
emit(PostLoadingState());
final posts = await repo.fetchPosts(page);
emit(PostLoadedState(posts: posts));
});
on<LoadMore>((event, emit) async{
if (controller.position.pixels ==
controller.position.maxScrollExtent) {
emit(LoadMoreState());
page++;
final posts = await repo.fetchPosts(page);
emit(PostLoadedState(posts: posts));
//  isLoadingMore = false;
} else {
print("not called");
}
});
}

}

And at home.dart:

import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:scroool/post_bloc.dart';
import 'package:scroool/post_events.dart';
import 'package:scroool/post_states.dart';
class Scroool extends StatelessWidget {
List posts = [];
@override
Widget build(BuildContext context) {
return Scaffold(
body: BlocConsumer<PostsBloc, PostsStates>(
listener: (context, state){},
builder: (context, state) {
if(state is PostLoadingState) {
return const Center(child: CircularProgressIndicator(),);
} else if(state is PostLoadedState) {
posts = posts + state.posts;
return ListView.builder(
controller: context.read<PostsBloc>().controller
..addListener(() => context.read<PostsBloc>().add(LoadMore())),
itemCount: state is LoadMoreState
? posts.length + 1 : posts.length ,
itemBuilder: (context, index) {
if(index < posts.length) {
final post = posts[index];
return Card(
child: ListTile(
leading: CircleAvatar(child: Text("${index + 1}"),),
title: Text(post['author'].toString()),
subtitle: Text(post['title']['rendered']),
)
);
} else {
return Center(child: CircularProgressIndicator(),);
}
},
);
} else {
return Container();
}
},
)
);
}
}

它的工作没有任何问题,但每次我需要加载更多的只是重新发出状态和显示数据从开始,我只需要继续更多的数据,而不是重新加载和添加所有的数据

更改您的BLoC状态,使父状态具有属性posts。您可以将不使用它的状态设置为空列表。

abstract class PostState {
final List<Post> posts;
PostState(this.posts);
}
class PostLoadingState extends PostState {
LoadMoreState() : super ([]);
}
class LoadMoreState extends PostState {
LoadMoreState({required List<Post> posts}) : super (posts);
}
class PostLoadedState extends PostState {
PostLoadedState({required List<Post> posts}) : super (posts);
}

然后相应地更改您的BLoC:

on<LoadMore>((event, emit) async{
if (controller.position.pixels ==
controller.position.maxScrollExtent) {
emit(LoadMoreState(posts: state.posts));
page++;
final posts = await repo.fetchPosts(page);
emit(PostLoadedState(posts: [...state.posts, ...posts]));
} else {
print("not called");
}
});

在您的小部件中删除posts变量,并使用posts从集团的状态。由于您的父状态有属性posts,您可以访问每个状态的posts,包括LoadMoreState。因此,将if条件更改为除PostLoadingState外的所有状态返回ListView

class Scroool extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
body: BlocConsumer<PostsBloc, PostsStates>(
listener: (context, state){},
builder: (context, state) {
if(state is PostLoadingState) {
return const Center(child: CircularProgressIndicator(),);
} else {
final posts = state.posts;
return ListView.builder(
controller: context.read<PostsBloc>().controller
..addListener(() => context.read<PostsBloc>().add(LoadMore())),
itemCount: state is LoadMoreState
? posts.length + 1 : posts.length ,
itemBuilder: (context, index) {
if(index < posts.length) {
final post = posts[index];
return Card(
child: ListTile(
leading: CircleAvatar(child: Text("${index + 1}"),),
title: Text(post['author'].toString()),
subtitle: Text(post['title']['rendered']),
)
);
} else {
return Center(child: CircularProgressIndicator(),);
}
},
);
}
},
)
);
}
}

最新更新