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

Time:02-24

When user logs into the app I need to set 'PWD' in the shared_preference variable. I need to get that value in splashcreen of my app so that when user opens the app again it need redirect to only password entering page. How can I do it in 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'));
          },

This what I am doing when user click login it will set to 'PWD', then I need to call the prefs in splashscree.

CodePudding user response:

Short Answer

Not for splash screen but I am using the same logic for the onboard screen. I hope this answer will help. So, on your main.dart file, create a nullable int onBoardCount, outside of any class, you're gonna need this on your splash screen. Also, instantiate SharedPreferences in main and pass it with onboardcount to you 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));
    }

Now, your MyApp file should be something like

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

Now in your splash_screen.dart use the following logic.

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

Long Answer

I am using Go Router for routing and Provider for state management so, here's my app's code.

Main.dart

int? onBoardCount;

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

  onBoardCount = prefs.getInt('onBoardKey');

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

I have a separate MyApp file to reduce congestion.

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);
        }),
      ),
    );
  }
}

App State Provider File

Create a function to update onboard logic and notify listeners.

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();
  }

  }

On Router file

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;
      });
}

Since the router is listening to appStateProvider, it will change once you call hasOnBoarded() on your onboard screen.

OnBoardScreen

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

I hope this will help please leave comments. FYI, ... is some other codes that I feel it's not important for this topic.

  • Related