我有一个带有文本字段的屏幕,当按下按钮时,它们被发送到一个cubit用于登录功能。我想做的是,当一个认证错误发生时,我想创建一个相关的小吃栏或对话框,但我有麻烦实现它。
文本字段:
CustomLoginTextField(
controller: emailController,
hint: 'ENTER YOUR EMAIL',
onChanged: (value) {
context.read<SigninCubit>().emailChanged(value);
//print(context.read<SigninCubit>().state.email);
},
),
CustomLoginTextField(
controller: passwordController,
hint: 'ENTER YOUR PASSWORD',
onChanged: (value) {
context.read<SigninCubit>().passwordChanged(value);
//print(context.read<SigninCubit>().state.password);
// print(passwordController.text);
},
),
相关按钮代码:
if (tabController.index == 3) {
context.read<SigninCubit>().signInWithCredentials();
}
腕尺状态:
part of 'signin_cubit.dart';
enum SigninStatus { initial, submitting, success, error }
class SigninState extends Equatable {
final String email;
final String password;
final SigninStatus status;
bool get isFormValid => email.isNotEmpty && password.isNotEmpty;
const SigninState({
required this.email,
required this.password,
required this.status,
});
factory SigninState.initial() {
return SigninState(
email: '',
password: '',
status: SigninStatus.initial,
);
}
@override
bool get stringify => true;
@override
List<Object> get props => [email, password, status];
SigninState copyWith({
String? email,
String? password,
SigninStatus? status,
}) {
return SigninState(
email: email ?? this.email,
password: password ?? this.password,
status: status ?? this.status,
);
}
}
腕尺:
import 'package:bloc/bloc.dart';
import 'package:equatable/equatable.dart';
import 'package:hero/repository/auth_repository.dart';
part 'signin_state.dart';
class SigninCubit extends Cubit<SigninState> {
final AuthRepository _authRepository;
SigninCubit({required AuthRepository authRepository})
: _authRepository = authRepository,
super(SigninState.initial());
void emailChanged(String value) {
emit(state.copyWith(email: value, status: SigninStatus.initial));
}
void passwordChanged(String value) {
emit(state.copyWith(password: value, status: SigninStatus.initial));
}
void signInWithCredentials() async {
try {
await _authRepository.signInWithEmailAndPassword(
email: state.email, password: state.password);
emit(
state.copyWith(status: SigninStatus.success),
);
} catch (e) {
emit(state.copyWith(status: SigninStatus.error));
}
}
}
相关auth函数:
Future<User?> signInWithEmailAndPassword(
{required String email, required String password}) async {
try {
final credential = await _firebaseAuth.signInWithEmailAndPassword(
email: email, password: password);
final user = _userFromFirebaseUser(credential.user);
return user;
} catch (e) {
print(e);
}
}
在auth函数中,我如何将该错误转化为与文本字段显示在同一屏幕上的snackbar/对话框?它目前正在打印错误,但这对用户体验没有太大帮助。谢谢你,谢谢!
2条答案
按热度按时间bgibtngc1#
我会在你的
SigninCubit
和emit
对应的状态中捕获错误。实际上,您已经在使用emit(state.copyWith(status: SigninStatus.error));
执行此操作然后,您可以使用
BlocListener<SigninCubit, SigninState>
并侦听状态更改。每当你的状态发生变化,并且有一个status
SigninStatus.error
,你就想显示这个snackbar。它看起来像这样:
您也可以使用
BlocConsumer
,它结合了BlocListener
和BlocBuilder
。这样做的一个缺点是,只要状态是
SigninStatus.error
,每当状态对象发生任何变化时,都会再次显示snackbar。因此,您应该通过另一个变量(如
snackbarDisplayed
)来跟踪显示-snackbar-status,在显示后设置true
,并在发出新错误时重置为false
。或者你可以通过在你的状态中设置一个专用的可空的
error
字段来consume
错误,在显示snackbar后设置null
。在我最近的项目中,我使用了后一种方法。为此我的腕尺有方法
我在这里使用这个方法:
qxgroojn2#
}
在try块之后使用此代码,您需要Flutter中的Firebase身份验证包