如何在 flutter 中存储 SharedPreference 值并将其传递给其他页面?

How to store and pass SharedPreference value to other pages in flutter?

当用户登录应用程序时,我需要在 shared_preference 变量中设置 'PWD'。我需要在我的应用程序的启动画面中获取该值,以便当用户再次打开该应用程序时,它只需要重定向到密码输入页面。 flutter 怎么实现呢

onPressed: () async {
            SharedPreferences prefs = await SharedPreferences.getInstance();
            appdata.loginmode = prefs.setString('LOGIN_MODE', 'PWD');

            Navigator.push(
              context,
              MaterialPageRoute(builder: (context) => BottomNavigation()),
            );
            print('Shared....');
            print(prefs.getString('LOGIN_MODE'));
          },

这是我在用户点击登录时所做的,它将设置为 'PWD',然后我需要在 splashscree 中调用首选项。

简答

不适用于初始屏幕,但我对板载屏幕使用相同的逻辑。我希望这个答案会有所帮助。因此,在您的 main.dart 文件中,在任何 class 之外创建一个可为 null 的 int onBoardCount,您将需要在启动画面上使用它。此外,在 main 中实例化 SharedPreferences 并将其与 onboardcount 一起传递给您 MyApp();

 int? onBoardCount;     
    void main() async {
      WidgetsFlutterBinding.ensureInitialized();
      SharedPreferences prefs = await SharedPreferences.getInstance();
    // Get onboard count from prefs, if it already exists,if not it will return null
      onBoardCount = prefs.getInt('onBoardKey');  
    
      runApp(MyApp(prefs,onBoardCount));
    }

现在,您的 MyApp 文件应该类似于

class MyApp extends StatefulWidget {
  late SharedPreferences prefs;
....
MyApp(this.prefs,this.onBoardCount, ...);

现在在您的 splash_screen.dart 中使用以下逻辑。

 void onSubmitDone(AppStateProvider stateProvider, BuildContext context) {
        await prefs.setInt('onBoardKey', 0);
       // Some route logic like route.push("/home");
      }

长答案

我使用 Go Router 进行路由,使用 Provider 进行状态管理,所以这是我的应用代码。

Main.dart

int? onBoardCount;

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  SharedPreferences prefs = await SharedPreferences.getInstance();

  onBoardCount = prefs.getInt('onBoardKey');

    ....
  runApp(MyApp(prefs, onBoardCount));
}

我有一个单独的 MyApp 文件来减少拥塞。

my_app.dart

class MyApp extends StatefulWidget {
  late SharedPreferences prefs;
  int? onBoardCount;
  

  MyApp(this.prefs, this.onBoardCount,..... {Key? key})
      : super(key: key);

  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
// The appstate provider is handling app level state
  late AppStateProvider appStateProvider;

     @override
  void didChangeDependencies() {
    super.didChangeDependencies();
    appStateProvider = AppStateProvider(
        widget.onBoardCount, widget.prefs,....);
  }

 

  @override
  Widget build(BuildContext context) {
    return MultiProvider(
      providers: [
       ....
        ChangeNotifierProvider(
            create: (context) => AppStateProvider(
                widget.onBoardCount,
                widget.prefs,...)),
               
        Provider(
          create: (context) => AppRouter(
            appStateProvider: appStateProvider,
            onBoardCount: widget.onBoardCount,
            prefs: widget.prefs,
          ),
        ),   
        
      ],
      child: Builder(
        builder: ((context) {
          final GoRouter router = Provider.of<AppRouter>(context).router;

          return MaterialApp.router(
              routeInformationParser: router.routeInformationParser,
              routerDelegate: router.routerDelegate);
        }),
      ),
    );
  }
}

应用程序状态提供程序文件

创建一个函数来更新板载逻辑并通知侦听器。

class AppStateProvider with ChangeNotifier {
  AppStateProvider(this.onBoardCount, this.prefs,..);
  
  int? onBoardCount;
  late SharedPreferences prefs;
 

  bool? _isOnboarded;
  

  bool get isOnboard => _isOnboarded as bool;
 
  void hasOnBoarded() async {
    await prefs.setInt('onBoardKey', 0);
    _isOnboarded = true;

    notifyListeners();
  }

  }

在路由器文件上

class AppRouter {
  late AppStateProvider appStateProvider;
  late SharedPreferences prefs;
  
  int? onBoardCount;

  AppRouter({
    required this.appStateProvider,
    required this.onBoardCount,
    required this.prefs,
  });
  get router => _router;

  late final _router = GoRouter(
      refreshListenable: appStateProvider,
      initialLocation: "/",
      routes: [
        ...
      ],
      redirect: (state) {
        final String onboardLocation =
            state.namedLocation("Your Route name");

       

        bool isOnboarding = state.subloc == onboardLocation;
      
        bool? toOnboard = prefs.containsKey('onBoardKey') ? false : true;
     
        

        print("Is LoggedIn is $isLoggedIn");
        if (toOnboard) {
        return isOnboarding ? null : onboardLocation;
        }

        return null;
      });
}

由于路由器正在监听 appStateProvider,一旦您在板载屏幕上调用 hasOnBoarded(),它就会发生变化。

OnBoardScreen

void onSubmitDone(AppStateProvider stateProvider, BuildContext context) {
    stateProvider.hasOnBoarded();
    GoRouter.of(context).go("/");
  }

希望对您有所帮助,请发表评论。仅供参考,...是其他一些我认为对本主题不重要的代码。