状态变化的集团导航

Posted

技术标签:

【中文标题】状态变化的集团导航【英文标题】:Bloc navigation on state change 【发布时间】:2019-07-07 05:11:53 【问题描述】:

我是 Flutter bloc 的新手,我在 bloc 实现方面遇到了一些问题,我正在尝试在我的初始屏幕小部件中的状态更改后导航。

在状态更新到 InitSuccess 之后,它应该导航到 LoginScreen,但是这种导航会发生很多次。

我无法理解在状态更改为 InitSuccess 后该做什么,此后该集团保持活力并多次调用 LoginScreen

启动画面

class SplashScreen extends StatefulWidget 
  @override
  State<StatefulWidget> createState() => _SplashScreenState();


class _SplashScreenState extends State<SplashScreen> 
  SplashBloc _splashBloc;
  final _scaffoldKey = GlobalKey<ScaffoldState>();

  @override
  void initState() 
    _init();
    super.initState();
  

  @override
  void dispose() 
    _splashBloc.dispose();
    super.dispose();
  

  void _init() 
    Future.delayed(Duration.zero, () 
      checkDeviceConnection(context);
      BlocSupervisor().delegate = SplashBlocDelegate();
      final bool isios = Theme.of(context).platform == TargetPlatform.iOS;
      _splashBloc = SplashBloc(
        firebaseService: FirebaseService(context),
        authService: AuthService(context),
        devicesService: DevicesService(context),
      );
      _splashBloc.dispatch(SplashInitEvent(isIOS: isIOS));
    );

@override
  Widget build(BuildContext context) 
    SystemChrome.setEnabledSystemUIOverlays([]);
    return BlocBuilder<SplashEvent, SplashState>(
      bloc: _splashBloc,
      builder: (
        BuildContext context,
        SplashState state,
      ) 
        if (state is InitFailure) 
          Future.delayed(Duration.zero, () 
            showWarningSnackBar(_scaffoldKey, state.error);
          );
        

        if (state is InitSuccess) 
          Future.delayed(Duration.zero, () 
            Navigator.push(
              context,
              MaterialPageRoute(
                builder: (context) => LoginScreen(),
              ),
            );
          );
        

        return Scaffold(
          key: _scaffoldKey,
          body: Container(
            decoration: appScreenGradient,
            alignment: Alignment.center,
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: <Widget>[
                Image.asset(
                  "assets/images/splash_screen/logo_splash.png",
                  width: 172.88,
                  height: 144.55,
                  fit: BoxFit.contain,
                ),
                SizedBox(
                  height: 20.0,
                ),
                LoadingSpinner(
                  spinnerColor: Theme.of(context).primaryColorLight,
                ),
              ],
            ),
          ),
        );
      ,
    );
  

飞溅区

class SplashBloc extends Bloc<SplashEvent, SplashState> 
  final FirebaseService firebaseService;
  final DevicesService devicesService;
  final AuthService authService;
  final UserPreferences _userPreferences = UserPreferences();

  SplashBloc(
    @required this.firebaseService,
    @required this.devicesService,
    @required this.authService,
  );

  @override
  Stream<SplashEvent> transform(Stream<SplashEvent> events) 
    return (events as Observable<SplashEvent>).debounce(
        Duration(milliseconds: 500));
  

  @override
  get initialState => SplashInitial();

  @override
  Stream<SplashState> mapEventToState(currentState, event) async* 
    if (event is SplashInitEvent) 
      if (currentState is SplashInitial) 
        yield InitLoading();

        try 
          firebaseService.togglePerformanceCollection(true);
          firebaseService.firebaseCloudMessagingListeners();

          String firebaseToken = await firebaseService
              .getFirebaseMessagingToken();
          bool isRegistered =
              await _userPreferences.getIsDeviceRegistered() ?? false;

          if (!isRegistered) 
            final String platform = event.isIOS ? 'IOS' : 'android';
            final deviceInfo = await devicesService.getDeviceInfo(platform);
            isRegistered = await devicesService.register(
              deviceToken: firebaseToken,
              deviceInfo: deviceInfo,
            );
            if (isRegistered) 
              _userPreferences.setIsDeviceRegistered(true);
            
          

          yield InitSuccess();
         catch (e) 
          yield InitFailure(error: e.toString());
        
      
    

    if (event is SplashInitialEvent) 
      yield SplashInitial();
    
  

【问题讨论】:

这个问题可能对你有帮助:***.com/questions/54101589/… 【参考方案1】:

我找到了以下解决方案:

if (state is LoggedIn) 
  WidgetsBinding.instance.addPostFrameCallback((_)  
    // Navigation
  );

我用这个 addPostFrame 回调包裹了我的导航,以延迟它的出现。

【讨论】:

以上是关于状态变化的集团导航的主要内容,如果未能解决你的问题,请参考以下文章

如何将应用程序的状态更改为颤振中的集团

集团不更新状态。谁能告诉我这段代码有啥问题。这是我第一次尝试使用 bloc 架构

如何在上下文之间共享集团

联想集团“2022年及未来10大科技趋势”预测

比特小鹿集团CEO孔令挥:挖矿市场正在加速变化并面临不确定性,比特小鹿已做好应对

一公局集团召开334工程推进暨项目管理经验交流会