我正在构建一个带有 flutter bloc 的应用程序。我遇到的问题是我的 bloc 侦听器仅触发初始状态,而不触发后续状态更改。所有其他问题都没有帮助,因为我的状态扩展为可比较状态。下面是我的代码;
我的登录区块
import 'package:bloc/bloc.dart';
import 'package:mobile_app/classes/custom_exception.dart';
import 'package:mobile_app/repositories/auth_repository.dart';
import 'package:mobile_app/states/login_status.dart';
class LoginBloc extends Cubit<LoginState> {
LoginBloc(this.auth) : super(LoginState.initial());
final AuthRepository auth;
void login(String email, String password) async {
emit(state.copyWith(loginStatus: Status.LOADING, isAuthenticated: false));
final response = await auth.doLogin(email, password);
if (response is AppException) {
emit(state.copyWith(
loginStatus: Status.ERROR,
error: response.toString(),
isAuthenticated: false));
} else {
emit(
state.copyWith(loginStatus: Status.COMPLETED, isAuthenticated: true));
}
}
}
我的状态文件;
enum Status { INITIAL, LOADING, COMPLETED, ERROR }
class LoginState extends Equatable {
final Status loginStatus;
final String? error;
final bool isAuthenticated;
LoginState(
{required this.loginStatus, this.error, required this.isAuthenticated});
factory LoginState.initial() {
return LoginState(loginStatus: Status.INITIAL, isAuthenticated: false);
}
LoginState copyWith(
{required Status loginStatus,
String? error,
required bool isAuthenticated}) {
return LoginState(
loginStatus: loginStatus,
error: error,
isAuthenticated: isAuthenticated);
}
@override
List<Object?> get props => [loginStatus, error, isAuthenticated];
}
然后是我的听众
return BlocListener<LoginBloc, LoginState>(
listener: (context, state) {
if (state.loginStatus == Status.COMPLETED) {
Navigator.of(context).pushReplacementNamed('/dashboard');
}
if (state.loginStatus == Status.ERROR) {
final snackBar = SnackBar(
backgroundColor: Colors.black,
content: Text(state.error!),
);
ScaffoldMessenger.of(context).showSnackBar(snackBar);
}
print(state);
},
我知道每次状态更改只调用一次侦听器,但就好像侦听器没有注册任何状态更改一样。帮助将不胜感激!
答案 0 :(得分:0)
好的,所以我想我知道错误来自哪里。我有一个 blocbuilder,它根据当前状态显示不同的页面,这些页面包括具有 bloc 侦听器的登录页面。因此,我删除了 bloc 构建器,并返回了带有 bloc 侦听器的登录页面,应该按原样调用小吃吧。我使用了 blocconsumer 来实现我想要实现的目标。
class LoginScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return BlocConsumer<LoginBloc, LoginState>(
listener: (context, state) {
if (state is LoginError) {
final snackBar = SnackBar(
backgroundColor: Colors.black,
content: Text(state.error),
);
ScaffoldMessenger.of(context).showSnackBar(snackBar);
}
},
builder: (context, state) {
if (state is LoginLoading) {
return ProgressIndication();
} else if (state is LoginSuccess) {
return DashboardScreen();
}
return Login();
},
);
}
}