flutter bloc:更改新事件后状态不会改变

问题描述 投票:0回答:2

Bloc Listner 不会更改状态以导航到下一个屏幕

  1. import 'package:bloc/bloc.dart';
    import 'package:bloctest/bloc/events.dart';
    import 'package:bloctest/bloc/states.dart';
    
    class AppBloc extends Bloc<AppEvent,AppState>{
    
      AppBloc(AppState initialState):super(initialState){
    
        on<AppStartEvent>((event, emit) {
          emit(AppInitState());
        });
    
        on<NavigatorButtonPressed>((event, emit) {
          emit(NavigationSucceedState());
          print('navigation succeed');
        });
      }
    }
    
  2. Bloc Listner 屏幕

    import 'package:bloctest/bloc/bloc.dart';
    import 'package:bloctest/bloc/states.dart';
    import 'package:flutter/material.dart';
    import 'package:flutter_bloc/flutter_bloc.dart';
    
    import 'bloc/events.dart';
    import 'main2.dart';
    void main() {
      runApp(const MyApp());
    }
    
    class MyApp extends StatefulWidget {
      const MyApp({super.key});
    
      @override
      State<MyApp> createState() => _MyAppState();
    }
    
    class _MyAppState extends State<MyApp> {
      bool isNavigationSuccess=false;
      AppBloc appBloc=AppBloc(AppInitState());
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          home: BlocProvider<AppBloc>(
              create: (context)=>AppBloc(AppInitState())..add(AppStartEvent()),
              child: Scaffold(
                body: BlocListener<AppBloc, AppState>(
                  listener: (context , state)async{
    
                    if(state is NavigationSucceedState){
                   await Future.delayed(const Duration(seconds: 1));
                      Navigator.push(context, MaterialPageRoute(builder: (context)=>MyApp2()));
                    }
                  },
                  child:BlocBuilder<AppBloc,AppState>(
                  builder:(context,state){
                  context.read<AppBloc>().add(AppStartEvent());
                  return state is AppStartingState?const Center(child: CircularProgressIndicator(),):
                  Scaffold(
                        body: SafeArea(child: Center(
                          child: ElevatedButton(
                              onPressed: () {
                               appBloc.add(NavigatorButtonPressed());
                              },
                              child: const Text('tap to go to next page')),
                        )),
                      );
                   }
                ),
              ),
    
          ),
        )
        );
      }
    }
    
  3. 如何解决这个问题,我想在 bloclistner 检查状态后导航到下一个屏幕,但在我的 ui bloc listner 中不知道状态已更改,因此状态在发送到下一个后在 ((state,emit)) 上更改状态。

flutter flutter-bloc equatable onreadystatechange flutter-exception
2个回答
0
投票

试试这个:

class AppBloc extends Bloc<AppEvent,AppState>{

  AppBloc() : super(AppStartingState()){

    on<NavigatorButtonPressed>((event, emit) {
      emit(NavigationSucceedState());
      print('navigation succeed');
    });
  }
}

在用户界面中:

class _MyAppState extends State<MyApp> {
  bool isNavigationSuccess = false;

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: BlocProvider<AppBloc>(
        create: (context) => AppBloc(),
        child: BlocListener<AppBloc, AppState>(
          listener: (context, state) {
            if (state is NavigationSucceedState) {
              Future.delayed(const Duration(seconds: 1), () {
                Navigator.push(
                    context, MaterialPageRoute(builder: (context) => MyApp2()));
              });
            }
          },
          child: BlocBuilder<AppBloc, AppState>(
            builder: (context, state) => state is AppStartingState
                ? const Center(child: CircularProgressIndicator())
                : Scaffold(
                    body: SafeArea(
                      child: Center(
                        child: ElevatedButton(
                            onPressed: () {
                              context.read<AppBloc>.add(
                                NavigatorButtonPressed(),
                              );
                            },
                            child: const Text('tap to go to next page')),
                      ),
                    ),
                  ),
          ),
        ),
      ),
    );
  }
}

0
投票

问题的原因是块的实例,如果你看一下你在你的状态(AppBloc appBloc=AppBloc(AppInitState());)中创建的实例以及提供构造函数中的其他实例(create: (context)= >AppBloc(AppInitState())..add(AppStartEvent()),) 因此,如果您可以在侦听器中看到,您正在侦听状态从第二个块实例更改,但您正在向第一个实例添加事件,并且因为它们是不同的对象状态从一开始更改在一秒钟内不可用,因此您可以通过点击方法将事件添加到您提供的块中,通过 context.read().add 它将起作用。

© www.soinside.com 2019 - 2024. All rights reserved.