![](/img/trans.png)
[英]How to fix absence of state when adding another emit in flutter/bloc?
[英]emit another state when load more data with 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");
}
});
}
}
在家里。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();
}
},
)
);
}
}
它工作没有任何问题,但每次我需要加载更多只是重新发出 state 并从头开始显示数据,我只需要继续更多数据而不是重新加载并添加所有数据
更改您的 BLoC state,这样父级 state 将拥有财产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
变量并使用来自 bloc 的 state 的posts
。由于您的父 state 具有属性posts
,您可以访问每个 state 的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(),);
}
},
);
}
},
)
);
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.