dart 如何重定向用户到着陆页时,他们第一次安装使用goRouter

bnl4lu3b  于 12个月前  发布在  Go
关注(0)|答案(1)|浏览(116)

在我之前的方法中,我有一个Riverpod提供程序返回auth状态更改,我会简单地基于此在myapp的构建中进行重定向:

return user.when(
  data: (userData) {
    // if (userData != null) {
    return MaterialApp(
      title: 'Flutter Demo',
      debugShowCheckedModeBanner: false,
      themeMode: activetheme,
      theme: MyThemes.lightTheme,
      darkTheme: MyThemes.darkTheme,
      home: const MyHomePage(),
    );
     } else {
      //if user is null they have opened the app for the first time so we send them to the Welcome Page
      return MaterialApp(
        title: 'Flutter Demo',
        debugShowCheckedModeBanner: false,
        themeMode: activetheme,
        theme: MyThemes.lightTheme,
        darkTheme: MyThemes.darkTheme,
        home: const WelcomePage(),
      );
    }*/
  },
  loading: () =>
      const CircularProgressIndicator(), // Replace with your loading widget
  error: (error, stackTrace) => ErrorWidget('Error: $error'),
);

字符串
但现在我已经切换到GoRouter,我无法复制这一点,我试图做的是发送用户到他的着陆页,如果他们没有登录或至少匿名登录,我无法读取我的goRouter重定向构造函数内的AuthProvider,所以如何最好地做到这一点?

final goRouter = GoRouter(
  initialLocation: '/',
  navigatorKey: _rootNavigatorKey,
  debugLogDiagnostics: true,
  routes: [
    StatefulShellRoute.indexedStack(
      builder: (context, state, navigationShell) {
        return ScaffoldWithNestedNavigation(navigationShell: navigationShell);
      },
      branches: [
        StatefulShellBranch(
          navigatorKey: _shellNavigatorHomeKey,
          routes: [
            // Shopping Cart
            GoRoute(
              path: '/',
              builder: (BuildContext context, GoRouterState state) =>
                  const MyHomePage(),
              routes: [
                GoRoute(
                  path: 'settimer',
                  parentNavigatorKey: _rootNavigatorKey,
                  builder: (context, state) {
                    return SetTimer();
                  },
                ),
                GoRoute(
                  path: 'countdown',
                  parentNavigatorKey: _rootNavigatorKey,
                  builder: (context, state) {
                    return CountDownPage();
                  },
                ),
              ],
            ),
          ],
        ),
        StatefulShellBranch(
          navigatorKey: _shellNavigatorStatsKey,
          routes: [
            GoRoute(
              path: '/statspage',
              builder: (BuildContext context, GoRouterState state) =>
                  const StatsPage(),
            ),
          ],
        ),
        StatefulShellBranch(
          navigatorKey: _shellNavigatorMoreKey,
          routes: [
            GoRoute(
              path: '/morepage',
              builder: (BuildContext context, GoRouterState state) =>
                  const MorePage(),
            ),
          ],
        ),
      ],
    ),
  ],
);

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);

  await Firebase.initializeApp(
    options: DefaultFirebaseOptions.currentPlatform,
  );
  usePathUrlStrategy();
  runApp(const ProviderScope(
    child: MyApp(),
  ));
}

class MyApp extends ConsumerWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    final user = ref.watch(userAuthProvider);
//returns which theme is active light or dark
    final activetheme = ref.watch(thememodeProvider);
    return MaterialApp.router(
      title: 'Flutter Demo',
      routerConfig: goRouter,
      debugShowCheckedModeBanner: false,
      themeMode: activetheme,
      theme: MyThemes.lightTheme,
      darkTheme: MyThemes.darkTheme,
      //home: const MyHomePage(),
    );

zrfyljdw

zrfyljdw1#

参考下面的代码,并根据您的情况进行更改。
1.创建SharedPreferences提供程序。

@riverpod
SharedPreferences sharedPrefs(SharedPrefsRef ref) {
  return throw UnimplementedError();
}

字符串
1.在main.dart中搜索此提供程序。

Future<void> main() async {
  WidgetsFlutterBinding.ensureInitialized();

  // Get SharedPrefences
  final SharedPreferences sharedPrefs = await SharedPreferences.getInstance();

  runApp(
    ProviderScope(
      overrides: [
        sharedPrefsProvider.overrideWithValue(sharedPrefs),
      ],
      child: const MyApp(),
    ),
  );
}


1.制作一个引导控制器或其他东西。(在这个例子中,我在提供程序中使用了BuildContext,但是你应该在外部小部件中使用它,比如Lading页面跳过按钮或完成按钮。)

@riverpod
class OnboardingController extends _$OnboardingController {
  late final SharedPreferences _prefs;

  /// If prefs key is not exist, return true and show onboarding screen.
  @override
  bool build() {
    _prefs = ref.watch(sharedPrefsProvider);

    bool showOnboarding = _prefs.getBool('showOnboarding') ?? true; 

    return showOnboarding;
  }

  void completeShowOnboarding(BuildContext context) {
    state = false;
    _prefs.setBool('showOnboarding', false);
    if(context.mounted) context.go(AppRoute.splash.routePath); // Use your path.
  }
}


1.使GoRouter成为提供程序并在重定向中使用提供程序。

@riverpod
Raw<GoRouter> appRouter(AppRouterRef ref) {
  // Add your providers.
  final User? authState = ref.watch(authRepositoryProvider);
  final bool showOnboarding = ref.watch(onboardingControllerProvider);

  return GoRouter(
    navigatorKey: _rootNavigatorKey,
    initialLocation: AppRoute.splash.routePath,
    routes: [
      // Add your routes
    ],
    redirect: (context, state) {
      // If you run the app for the first time, the onboarding page is shown.
      if (showOnboarding) {
        return AppRoute.onboarding.routePath;
      }

      final isSplash = state.uri.toString() == AppRoute.splash.routePath;

      if (isSplash) {
        return authState == null
            ? AppRoute.auth.routePath
            : AppRoute.home.routePath;
      }

      return null;
    },
  );
}

相关问题