flutter - 在我的肘部发出变化状态不会为我的听众产生事件
问题描述
我的屏幕如下所示:
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:app/flows/splashscreen/splash_screen_cubit.dart';
import 'package:flutter_spinkit/flutter_spinkit.dart';
import 'package:rflutter_alert/rflutter_alert.dart';
class SplashScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return BlocConsumer<SplashScreenCubit, SplashScreenState>(
listener: (context, state) {
debugPrint("listener received something");
if (state is SplashScreenCheckingToken) {
debugPrint("state is SplashScreenCheckingToken");
context.bloc<SplashScreenCubit>().checkingAccessToken();
} else if (state is SplashScreenTokenValid) {
Navigator.pushNamed(context, '/home');
} else if (state is SplashScreenTokenInvalid) {
Navigator.pushNamed(context, '/landing-page');
} else if (state is SplashScreenError) {
_showError(context);
}
}, builder: (context, state) {
if (state is SplashScreenInitial) {
debugPrint("state is SplashScreenInitial");
context
.bloc<SplashScreenCubit>()
.checkAccessToken(); // doesn't work, but why?
// context.bloc<SplashScreenCubit>().checkingAccessToken(); // works
return Scaffold(
body:
Container(color: Colors.green, child: _loadingWidget(context)));
} else {
return Container();
}
});
}
SpinKitChasingDots _loadingWidget(BuildContext context) {
return SpinKitChasingDots(
color: Colors.white,
size: 50.0,
);
}
Future<bool> _showError(BuildContext context) {
return Alert(context: context, title: "Error", desc: "Something went wrong")
.show();
}
}
我的肘部是这样的:
import 'package:bloc/bloc.dart';
import 'package:flutter/material.dart';
import 'package:app/repository/api_repository.dart';
part 'splash_screen_state.dart';
class SplashScreenCubit extends Cubit<SplashScreenState> {
final APIRepository _apiRepository;
SplashScreenCubit(this._apiRepository) : super(SplashScreenInitial());
void checkAccessToken() {
debugPrint("checkAccessToken begin");
emit(SplashScreenCheckingToken());
debugPrint("checkAccessToken finished");
}
Future<void> checkingAccessToken() async {
try {
final quote = await _apiRepository.fetchQuote();
debugPrint(quote.toString());
emit(SplashScreenTokenValid());
} on Error {
emit(SplashScreenError());
}
}
void accessTokenValid() {
emit(SplashScreenTokenValid());
}
void accessTokenInvalid() {
emit(SplashScreenTokenInvalid());
}
}
我的状态如下:
part of 'splash_screen_cubit.dart';
enum SplashScreenStateEnum {
Initial,
CheckingToken,
TokenValid,
TokenInvalid,
Error,
}
abstract class SplashScreenState {
final SplashScreenStateEnum splashScreenStateEnum;
const SplashScreenState(this.splashScreenStateEnum);
}
class SplashScreenInitial extends SplashScreenState {
const SplashScreenInitial() : super(SplashScreenStateEnum.Initial);
}
class SplashScreenCheckingToken extends SplashScreenState {
const SplashScreenCheckingToken()
: super(SplashScreenStateEnum.CheckingToken);
@override
bool operator ==(Object o) {
if (identical(this, o)) return true;
return o is SplashScreenCheckingToken &&
o.splashScreenStateEnum == splashScreenStateEnum;
}
@override
int get hashCode => splashScreenStateEnum.hashCode;
}
class SplashScreenTokenValid extends SplashScreenState {
const SplashScreenTokenValid() : super(SplashScreenStateEnum.TokenValid);
@override
bool operator ==(Object o) {
if (identical(this, o)) return true;
return o is SplashScreenTokenValid &&
o.splashScreenStateEnum == splashScreenStateEnum;
}
@override
int get hashCode => splashScreenStateEnum.hashCode;
}
class SplashScreenTokenInvalid extends SplashScreenState {
const SplashScreenTokenInvalid() : super(SplashScreenStateEnum.TokenInvalid);
@override
bool operator ==(Object o) {
if (identical(this, o)) return true;
return o is SplashScreenTokenInvalid &&
o.splashScreenStateEnum == splashScreenStateEnum;
}
@override
int get hashCode => splashScreenStateEnum.hashCode;
}
class SplashScreenError extends SplashScreenState {
const SplashScreenError() : super(SplashScreenStateEnum.Error);
@override
bool operator ==(Object o) {
if (identical(this, o)) return true;
return o is SplashScreenError &&
o.splashScreenStateEnum == splashScreenStateEnum;
}
@override
int get hashCode => splashScreenStateEnum.hashCode;
}
当我运行程序时,会打印以下内容:
flutter: state is SplashScreenInitial
flutter: checkAccessToken begin
flutter: checkAccessToken finished
这意味着尽管 Cubit 中的 checkAccessToken() 函数被触发,但 SplashScreen 上 BlocConsumer 的侦听器中没有事件进入。
否则它会打印:
"listener received something"
我不知道为什么,因为当我尝试 Cubit 中的 checksAccessToken() 函数时,这确实会为侦听器产生事件。
解决方案
您SplashScreenCheckingToken
负责所有其他“重定向”状态,但它从未被触发。也许你可以做的是在初始化之后修改你的cubit构造函数。
class SplashScreenCubit extends Cubit<SplashScreenState> {
final APIRepository _apiRepository;
SplashScreenCubit(this._apiRepository) : super(SplashScreenInitial()) {
emit(SplashScreenCheckingToken());
}
...
}
那应该解决它。