使用Bloc模式来显示从REST API获取的数据列表。
现在我想在按钮点击时更新列表视图。
当我点击按钮时,它会获取数据,但不会更新列表视图。
以下是完整的代码。
main.dart
import 'package:bloc_demo/homepage.dart';
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: HomePage(),
);
}
}
HomePage.dart
class HomePage extends StatelessWidget {
String pageNo = "1";
@override
Widget build(BuildContext context) {
return MultiBlocProvider(
providers: [
BlocProvider<UserBloc>(
create: (BuildContext context) => UserBloc(UserRepository(),pageNo),
),
],
child: Scaffold(
appBar: AppBar(title: const Text('The BloC App')),
body: blocBody(),
floatingActionButton: FloatingActionButton(
onPressed: () {
pageNo = "2";
UserBloc(
UserRepository(),pageNo,
).add(LoadUserEvent());
},
child: const Icon(Icons.navigation),
),
),
);
}
Widget blocBody() {
return BlocProvider(
create: (context) => UserBloc(
UserRepository(),pageNo,
)..add(LoadUserEvent()),
child: BlocBuilder<UserBloc, UserState>(
builder: (context, state) {
if (state is UserLoadingState) {
return const Center(
child: CircularProgressIndicator(),
);
}
if (state is UserLoadedState) {
List<UserModel> userList = state.users;
return ListView.builder(
itemCount: userList.length,
itemBuilder: (_, index) {
return Padding(
padding:
const EdgeInsets.symmetric(vertical: 4, horizontal: 8),
child: Card(
color: Theme.of(context).primaryColor,
child: ListTile(
title: Text(
'${userList[index].firstName} ${userList[index].lastName}',
style: const TextStyle(color: Colors.white),
),
subtitle: Text(
'${userList[index].email}',
style: const TextStyle(color: Colors.white),
),
leading: CircleAvatar(
backgroundImage: NetworkImage(
userList[index].avatar.toString()),
))),
);
});
}
if (state is UserErrorState) {
return const Center(
child: Text("Error"),
);
}
return Container();
},
),
);
}
}
UserBloc
class UserBloc extends Bloc<UserEvent, UserState> {
final UserRepository _userRepository;
final String pageNo;
UserBloc(this._userRepository,this.pageNo) : super(UserLoadingState()) {
on<LoadUserEvent>((event, emit) async {
emit(UserLoadingState());
try {
final users = await _userRepository.getUsers(pageNo);
emit(UserLoadedState(users));
} catch (e) {
emit(UserErrorState(e.toString()));
}
});
}
}
UserEvent
@immutable
abstract class UserEvent extends Equatable {
const UserEvent();
}
class LoadUserEvent extends UserEvent {
@override
List<Object?> get props => [];
}
UserState
@immutable
abstract class UserState extends Equatable {}
//data loading state
class UserLoadingState extends UserState {
@override
List<Object?> get props => [];
}
class UserLoadedState extends UserState {
final List<UserModel> users;
UserLoadedState(this.users);
@override
List<Object?> get props => [users];
}
class UserErrorState extends UserState {
final String error;
UserErrorState(this.error);
@override
List<Object?> get props => [error];
}
UserModel
class UserModel {
int? id;
String? email;
String? firstName;
String? lastName;
String? avatar;
UserModel({this.id, this.email, this.firstName, this.lastName, this.avatar});
UserModel.fromJson(Map<String, dynamic> json) {
id = json['id'];
email = json['email'];
firstName = json['first_name'];
lastName = json['last_name'];
avatar = json['avatar'];
}
}
UserRepository
class UserRepository {
String userUrl = 'https://reqres.in/api/users?page=';
Future<List<UserModel>> getUsers(String pageNo) async {
Response response = await get(Uri.parse(userUrl+pageNo));
if (response.statusCode == 200) {
final List result = jsonDecode(response.body)['data'];
return result.map((e) => UserModel.fromJson(e)).toList();
} else {
throw Exception(response.reasonPhrase);
}
}
}