繁体   English   中英

状态或事件在颤振块中没有改变

[英]State or event not getting changed in flutter bloc

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


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 类中定义的基块。 我定义的子块工作正常,它也在发送事件。 我的问题是我无法更改父集团的状态。 有人能告诉我我做错了什么吗? 任何帮助将不胜感激。 谢谢...

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

有关更多信息,请参阅此示例。

Flutter Bloc with Stream

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM