gpt4 book ai didi

flutter - 状态或事件在 flutter bloc 中没有改变

转载 作者:行者123 更新时间:2023-12-03 03:50:37 26 4
gpt4 key购买 nike

我已经按照以下方式定义了一个抽象的无状态小部件


abstract class BaseStatelessWidget<T extends Bloc> extends StatelessWidget {
@override
Widget build(BuildContext context) {
if (shouldHideStatusBar) {
SystemChrome.setEnabledSystemUIOverlays([]);
}

return MultiBlocProvider(
providers: [
BlocProvider(
create: (context) {
BaseBloc baseBloc = getIt<BaseBloc>();
baseBloc.add(BaseEvent.networkListeningInitiated());
return baseBloc;
},
),
BlocProvider(
create: (context) => getImplementedBloc(context),
),
],
child: BlocListener<BaseBloc, BaseState>(
listener: _handleState,
child: buildScreen(context),
),
);
}

bool get shouldHideStatusBar => false;

_handleState(BuildContext context, BaseState state) {
// here different state will be managed
}


Widget buildScreen(BuildContext context);

T getImplementedBloc(BuildContext context);
}



另一个无状态小部件 SigninPage 按照以下方式扩展它

class SigninPage extends BaseStatelessWidget<SigninBloc> {
@override
Widget buildScreen(BuildContext context) {
return Scaffold(
body: SingleChildScrollView(
child: SigninForm(),
),
resizeToAvoidBottomInset: true,
);
}

@override
bool get shouldHideStatusBar => true;

@override
SigninBloc getImplementedBloc(BuildContext context) {
return getIt<SigninBloc>();
}
}

为了这个问题,我从 SingInForm 类中删除了冗余代码,这里是代码:

class SigninForm extends StatelessWidget {
@override
Widget build(BuildContext context) {
return PrimaryButton(
btnText: getString(context, StringKeys.signin),
onButtonClick: () => onSignin(context),
);
}

onSignin(BuildContext context) {
context.bloc<BaseBloc>().add(BaseEvent.changeLoaderStatus(visible: true)); => this is not working I tried to check if it is null. this is not null
context.bloc<SigninBloc>().add(SigninEvent.loginWithEmailPassword()); => this is working fine
}
}

这是我定义的 BaseBloc 类。 mapEventToState() 方法和 onTransition() 方法均未被调用。

import 'dart:async';

import 'package:connectivity/connectivity.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:injectable/injectable.dart';
import 'package:refyne_app/domain/core/i_network_aware_facade.dart';
import 'package:refyne_app/domain/core/logger.dart';
import 'package:refyne_app/infrastructure/core/api_service/connectivity_status.dart';

part 'base_event.dart';
part 'base_state.dart';
part 'base_bloc.freezed.dart';

@injectable
class BaseBloc extends Bloc<BaseEvent, BaseState> {
INetworkAwareFacade _networkHandlerFacade;

BaseBloc(this._networkHandlerFacade)
: super(BaseState.initial(
isLoaderVisible: false,
));

@override
Stream<BaseState> mapEventToState(
BaseEvent event,
) async* {
yield* event.map(
networkListeningInitiated: (_) => _handleNetworkChange(), <== This one is causing the issue, if i remove this method. It works fine.
networkListeningStopped: (_) async* {},
changeLoaderStatus: (ChangeLoaderStatus value) async* {
logger.d('from bloc loader called with $value');
yield state.copyWith(isLoaderVisible: value.visible);
},
);
}

Stream<BaseState> _handleNetworkChange() async* {
await for (ConnectivityResult result
in _networkHandlerFacade.onConnectionChange()) { <== onConnectionChange will give you a stream
if (result == ConnectivityResult.none) {
yield state.copyWith(
connectionStatus: ConnectionStatus(
type: ConnectionType.NONE,
isworking: false,
));
} else {
bool isworking = await _networkHandlerFacade.checkConnection();
ConnectionType type = result == ConnectivityResult.mobile
? ConnectionType.MOBILE
: ConnectionType.WIFI;

yield state.copyWith(
connectionStatus: ConnectionStatus(type: type, isworking: isworking),
);
}
}
}

@override
void onError(Object error, StackTrace stackTrace) {
if (error is Exception) {
_handleException(error);
} else {
super.onError(error, stackTrace);
// TODO:: handle this exception scenario
}
}

_handleException(Exception e) {
print(e);
}

@override
void onTransition(Transition<BaseEvent, BaseState> transition) {
logger.d('from base bloc ${transition.event}');
logger.d('from base bloc ${transition.currentState}');
logger.d('from base bloc ${transition.nextState}');
super.onTransition(transition);
}
}


我正在尝试访问 BaseStatelessWidget 类中定义的基 block 。我定义的子 Bloc 工作正常,它也在发送事件。我的问题是我无法更改父 Bloc 的状态。有人可以告诉我我做错了什么吗?任何帮助将不胜感激。谢谢...

最佳答案

折腾了一整天,终于明白为什么会这样了。我直接在 mapEventToState 方法中处理流。当我将流处理从 mapEventToState 移动到构造函数时,它工作正常。希望它能帮助某人...

有关详细信息,请参阅此示例。

Flutter Bloc with Stream

关于flutter - 状态或事件在 flutter bloc 中没有改变,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63596443/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com