如何将 flutter_bloc 与 go_router 一起使用

ism*_*isi 10 flutter flutter-navigation flutter-bloc

我构建了一个使用 flutter_bloc 的应用程序。我想使用 go_router 进行导航。但是对于动态路由,我如何将 GoRouter refreshListener 参数与 flutter_bloc 一起使用

GoRouter(
  routes: [
    GoRoute(
      path: '/',
      name: 'home',
      pageBuilder: (context, state) => HomePage.page(),
    ),
    GoRoute(
      path: '/login',
      name: 'login',
      pageBuilder: (context, state) => LoginPage.page(),
    ),
  ],
  redirect: (state) {
    final isLoggedIn =
        bloc.state.status == AuthenticationStatus.authenticated;
    final isLoggingIn = state.location == '/login';

    if (!isLoggingIn && !isLoggingIn) return '/login';
    if (isLoggedIn && isLoggingIn) return "/";

    return null;
  },
  refreshListenable: 
   );
Run Code Online (Sandbox Code Playgroud)

小智 9

由于 bloc 也以流的形式返回状态,因此您可以直接使用它。你可以这样做->

refreshListenable = GoRouterRefreshStream(authenticationBloc.stream),
Run Code Online (Sandbox Code Playgroud)

  • 这已在 GoRouter v5 中删除。请参阅迁移指南:https://flutter.dev/go/go-router-v5-writing-changes (8认同)

ism*_*isi 7

对我来说,将changeNotifier与Bloc类混合并从事件中调用notifyListener()是有效的

这是我的集体课

class AuthenticationBloc extends Bloc<AuthenticationEvent, AuthenticationState>
    with ChangeNotifier {
  AuthenticationBloc(
      {required AuthenticationRepository authenticationRepository})
      : _authenticationRepository = authenticationRepository,
        super(const AuthenticationState.unknown()) {
    on<AppStarted>(_onAppStarted);

    on<AuthenticationUserChanged>(_onAuthenticationUserChanged);

    on<AuthenticationLogoutRequested>(_onAuthenticationLogoutRequested);

    _userSubscription = _authenticationRepository.user
        .listen((user) => add(AuthenticationUserChanged(user)));
  }

  final AuthenticationRepository _authenticationRepository;

  late StreamSubscription<User> _userSubscription;


  @override
  Future<void> close() {
    _userSubscription.cancel();
    return super.close();
  }


  FutureOr<void> _onAppStarted(
      AppStarted event, Emitter<AuthenticationState> emit) {
    emit(AuthenticationState.unknown());
  }

  FutureOr<void> _onAuthenticationUserChanged(
      AuthenticationUserChanged event, Emitter<AuthenticationState> emit) {
    final status = event.user != User.empty
        ? AuthenticationState.authenticated(event.user)
        : const AuthenticationState.unauthenticated();
    emit(status);
    notifyListeners();
  }

  FutureOr<void> _onAuthenticationLogoutRequested(
      AuthenticationLogoutRequested event, Emitter<AuthenticationState> emit) {
    unawaited(_authenticationRepository.logOut());
  }
}
Run Code Online (Sandbox Code Playgroud)

这是GoRouter

GoRouter routes(AuthenticationBloc bloc) {
  return GoRouter(
      routes: [
        GoRoute(
          path: '/',
          name: 'home',
          builder: (context, state) => const HomePage(),
        ),
        GoRoute(
          path: '/login',
          name: 'login',
          builder: (context, state) => const LoginPage(),
        ),
      ],
      redirect: (state) {
        final isLoggedIn =
            bloc.state.status == AuthenticationStatus.authenticated;
        final isLoggingIn = state.location == '/login';
        print(isLoggedIn);

        if (!isLoggedIn && !isLoggingIn) return '/login';
        if (isLoggedIn && isLoggingIn) return '/';

        return null;
      },
      refreshListenable: bloc);
}
Run Code Online (Sandbox Code Playgroud)


聂超群*_*聂超群 1

也许你可以这样做:

class AuthStateNotifier extends ChangeNotifier {
  late final StreamSubscription<AuthState> _blocStream;
  AuthStateProvider(AuthBloc bloc) {
    _blocStream = bloc.stream.listen((event) {
      notifyListeners();
    });
  }

  @override
  void dispose() {
    _blocStream.cancel();
    super.dispose();
  }
}
Run Code Online (Sandbox Code Playgroud)

代码来自这个答案,希望你明白。