Shared Preferences key value not changing - flutter

I want to write code that directs the user to a welcome page if it's the first time the app is being run. After the user logs in, any subsequent launches of the app direct the user to log in, skipping the welcome page. It seems that when I try to set the value of my key upon logging in, it's not changing, because after logging in, closing the app and launching it again it's still going to the welcome page. How do I fix this? I'm not sure whether the issue is with the initialisation or the setting of the value upon login.
Here's the initialisation of my app:
import 'package:screens/welcomepages/signup_or_login.dart';
import 'package:screens/welcomepages/welcome.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:config/theme.dart';
import 'package:shared_preferences/shared_preferences.dart';
Future<SharedPreferences> _prefs = SharedPreferences.getInstance();
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();
SystemChrome.setSystemUIOverlayStyle(const SystemUiOverlayStyle(
statusBarColor: Colors.transparent,
statusBarBrightness: Brightness.dark));
runApp(MyApp(prefs: await _prefs));
}
class MyApp extends StatefulWidget {
const MyApp({Key? key, this.title, required this.prefs})
: super(key: key);
final String? title;
final SharedPreferences prefs;
#override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
late SharedPreferences prefs;
#override
void initState() {
super.initState();
initializePreference();
}
Future<void> initializePreference() async {
prefs = await SharedPreferences.getInstance();
setState(() {
prefs.setBool("hasLoggedIn", false);
});
}
#override
Widget build(BuildContext context) {
if (prefs.getBool("hasLoggedIn") == false) {
return MaterialApp(
theme: theme(),
debugShowCheckedModeBanner: false,
home: Welcome(prefs: prefs),
);
}
return MaterialApp(
theme: theme(),
debugShowCheckedModeBanner: false,
home: SignUpOrLogIn(prefs: prefs),
);
}
}
And here's the relevant parts of my log in page
import 'package:services/auth/auth_service.dart';
import 'package:widgets/text_fields_widgets/email_textfield.dart';
import 'package:widgets/text_fields_widgets/password_textfeild.dart';
import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';
class Login extends StatefulWidget {
const Login({Key? key, required this.prefs}) : super(key: key);
final SharedPreferences prefs;
#override
_LoginState createState() => _LoginState(prefs);
}
class _LoginState extends State<Login> {
late final SharedPreferences prefs;
_LoginState(SharedPreferences prefs);
Future<void> initializePreference() async {
prefs = await SharedPreferences.getInstance();
}
#override
void initState() {
super.initState();
initializePreference().whenComplete(() {
setState(() {
prefs.getBool("isFirstRun");
});
});
}
#override
Widget build(BuildContext context) {
Material btnLogin = loginBTN(context);
return Scaffold(
.....
Padding(
padding: const EdgeInsets.all(8.0),
child: btnLogin,
)
}
Material loginBTN(BuildContext context) {
// ignore: unused_local_variable
final btnLogin = Material(
elevation: 5,
borderRadius: BorderRadius.circular(30),
color: Theme.of(context).primaryColor,
child: MaterialButton(
padding: const EdgeInsets.fromLTRB(20, 15, 20, 15),
minWidth: MediaQuery.of(context).size.width,
onPressed: () async {
setState(() {
prefs.setBool("hasLoggedIn", true);
});
setState(
() => loadingAnimation = true,
);
await Future.delayed(const Duration(seconds: 1));
setState(
() => loadingAnimation = false,
);
await Authservice().logInMethod(
emailController.text, passwordController.text, context, _formKey);
},
child: loadingAnimation
? const CircularProgressIndicator(
color: Colors.white,
)
: const Text(
"Log in",
textAlign: TextAlign.center,
style: TextStyle(fontSize: 24, color: Colors.white),
),
),
);
return btnLogin;
}
}
Sorry for how lengthy this is, tried to shorten it to only provide what's relevant.

Your are calling initializePreference() inside initState() and that function set hasLoggedIn to false. So even if you set it to true in your login page, when restarting the app it will be set again to false.

Try this brother
if (prefs.getBool("hasLoggedIn") == null || prefs.getBool("hasLoggedIn") == false) {
return MaterialApp(
theme: theme(),
debugShowCheckedModeBanner: false,
home: Welcome(prefs: prefs),
);
}

Related

flutter - Variable that changed the value using sharedPreferences does not work properly -Has a simple example code

I created a button that allows users to change the size of letters.
I hope that the font size value will remain changed even if I run the app again.
But in my code, it goes back to its original state.I made a simple code of the problem I faced. I made three files.
1.HomePage.dart
import 'dart:async';
import 'dart:convert';
// import 'package:google_mobile_ads/google_mobile_ads.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:provider/provider.dart';
import 'package:shared_preferences/shared_preferences.dart';
import './main.dart';
import './count_page.dart';
class HomePage extends StatefulWidget {
const HomePage({Key? key}) : super(key: key);
#override
State<HomePage> createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
late CountPage _countPage;
#override
Widget build(BuildContext context) {
String prefsFont = "prefs_font";
_countPage = Provider.of<CountPage>(context, listen: true);
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.green,
title: Text('Test_Code'),
centerTitle: true, // 중앙 정렬
elevation: 0.0,
),
body: Container(
color: Colors.white,
child: Text('Font_size',style: TextStyle(fontSize: _countPage.font),),
),
bottomNavigationBar: BottomAppBar(
color: Colors.lime,
child: Container(
height: 200,
child: Row(
children: [
IconButton(
onPressed: () async {
SharedPreferences prefs = await SharedPreferences.getInstance();
await prefs.setDouble('prefs_font', 10);
setState(() {
_countPage.font = (prefs.getDouble('prefs_font') ?? 40) ;
});
},
icon: Icon(Icons.looks_one_outlined)),
IconButton(
onPressed: () async {
SharedPreferences prefs = await SharedPreferences.getInstance();
await prefs.setDouble('prefs_font', 40);
setState(() {
_countPage.font = (prefs.getDouble('prefs_font') ?? 40) ;
});
},
icon: Icon(Icons.looks_two_outlined)),
IconButton(
onPressed: () async {
SharedPreferences prefs = await SharedPreferences.getInstance();
await prefs.setDouble('prefs_font', 80);
setState(() {
_countPage.font = (prefs.getDouble('prefs_font') ?? 40) ;
});
},
icon: Icon(Icons.looks_3_outlined)),
],
),
),
),
);
}
}
2.main.dart
import 'dart:convert';
// import 'package:google_mobile_ads/google_mobile_ads.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:provider/provider.dart';
import 'package:shared_preferences/shared_preferences.dart';
import './HomePage.dart';
import 'count_page.dart';
void main() {
// WidgetsFlutterBinding.ensureInitialized();
// MobileAds.instance.initialize();
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return ChangeNotifierProvider(
create: (BuildContext context) => CountPage(),
child: MaterialApp(
debugShowCheckedModeBanner: false,
theme: ThemeData(
primarySwatch: Colors.blue,
splashColor: Colors.transparent,
highlightColor: Colors.transparent,
),
home: HomePage(),
),
);
}
}
3.count_page.dart
import 'dart:ui';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';
class CountPage extends ChangeNotifier {
double _font = 40;
double get font => _font;
set font(double font) {
_font = font;
}
}
I made it small so that the composition is similar to the project I am working on.
The value changes even if you press the button, but it goes back to the beginning when you run the app again.
What is the problem?
So basically what's happening here is, you're only storing the font inside your SharedPrefrence. But you're not fetching it back when the app starts. Your CountPage class isn't storing the font size. It's shared preference that's storing it. So you have to just fetch the data from SharedPrefrence on the app start. And then use it in your code. A small example will be
Initialize SharedPrefrence so you can use later.
void main() async {
WidgetsFlutterBinding.ensureInitialized();
final sharedPref = await SharedPrefrence.getInstance(); // Instance will be created.
runApp(const MyApp());
}
2.Then make your class use SharedPrefrence instance by default
class CountPage extends ChangeNotifier {
final SharedPrefrence pref;
CountPage({required this.pref});
double get font => pref.getDouble('prefs_font') ?? 40;
setFont(double font) async {
await prefs.setDouble('prefs_font', font);
notifyListeners(); //This is necessary so that when the value changes the UI gets an update.
}
}
Then pass the SharedPrefrence instance to that class, so it can use it.
class MyApp extends StatelessWidget {
final SharedPrefrence pref;
const MyApp({Key? key, required this.pref}) : super(key: key); // Getting the instance from main.
#override
Widget build(BuildContext context) {
return ChangeNotifierProvider(
create: (BuildContext context) => CountPage({pref: pref}),//Passing the instance.
child: MaterialApp(
debugShowCheckedModeBanner: false,
theme: ThemeData(
primarySwatch: Colors.blue,
splashColor: Colors.transparent,
highlightColor: Colors.transparent,
),
home: HomePage(),
),
);
}
}
Also on your save button it looks like you're using a getter to set the value, which shouldn't work. But now you can just call it like this
onPressed: () async {
setState(() { // Now this setState is optional bcz you're saying the notifier to notify it's listeners, whenever you're setting the value.
await _countPage.setFont(\* font size for this button */);
});
},

Flutter Onboarding Screen Only Once With Splash Screen

I was working in Flutter to make an app and I only want the onboarding screen to be seen once by users. I have watched several videos showing how to do this, but the problem is my home screen will always be the Splash Screen. I am not sure how to use Shared Preferences to have the onboarding screen shown once but to still have the splash screen show every time. I could really use some assistance :).
My code for main.dart:
int? isViewed;
Future <void> main() async {
WidgetsFlutterBinding.ensureInitialized();
final prefs = await SharedPreferences.getInstance();
final showLogin = prefs.getBool('showLogin') ?? false;
Paint.enableDithering = true;
await Firebase.initializeApp();
// This is for our onboarding screen
isViewed = prefs.getInt('onboard');
runApp(MyApp(showLogin: showLogin));
}
class MyApp extends StatelessWidget {
final bool showLogin;
const MyApp({Key? key,
required this.showLogin}) : super(key: key);
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Strength',
debugShowCheckedModeBanner: false,
theme: ThemeData(
appBarTheme: const AppBarTheme(color: Colors.white,
elevation: 0,
brightness: Brightness.light,
iconTheme: IconThemeData(color: Colors.black),
textTheme: TextTheme(headline6: TextStyle(color: Color(0xff888888), fontSize: 18),
)
),),
home: const SplashScreen(),
);
}
}
Chunks of code for my onboarding screen:
class OnboardingScreen extends StatefulWidget {
const OnboardingScreen({Key? key}) : super(key: key);
#override
_OnboardingScreenState createState() => _OnboardingScreenState();
}
class _OnboardingScreenState extends State<OnboardingScreen> {
final controller = PageController();
bool isLastPage = false;
#override
void dispose() {
controller.dispose();
super.dispose();
}
_storeOnboardingInfo() async {
int isViewed = 0;
SharedPreferences prefs = await SharedPreferences.getInstance();
await prefs.setInt('onBoard', isViewed);
}
#override
Widget build(BuildContext context) {
Size size = MediaQuery.of(context).size;
.
.
.
TextButton(
style: TextButton.styleFrom(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(0),
),
primary: Colors.white,
backgroundColor: const Color(0xff31708c),
minimumSize: const Size.fromHeight(60)
),
child: Text(
'Get Started',
style: GoogleFonts.montserrat(
fontSize: 24,
fontWeight: FontWeight.w600),
),
onPressed: () async {
final prefs = await SharedPreferences.getInstance();
prefs.setBool('showLogin', true);
await _storeOnboardingInfo();
Navigator.of(context).pushReplacement(
PageTransition(
type: PageTransitionType.fade,
duration: const Duration(milliseconds: 500),
child: LandingScreen()
)
);
}
)
Code for my Splash screen:
class SplashScreen extends StatefulWidget {
const SplashScreen ({Key? key}) : super(key: key);
#override
_SplashScreenState createState() => _SplashScreenState();
}
class _SplashScreenState extends State<SplashScreen> with TickerProviderStateMixin{
late AnimationController _screenController;
#override
void initState() {
super.initState();
_screenController = AnimationController(vsync: this);
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
height: double.infinity,
width: double.infinity,
child: Lottie.asset('assets/lottie/splashScreen.lottie.json',
fit: BoxFit.fill,
controller: _screenController,
onLoaded: (composition) {
_screenController
..duration = composition.duration
..forward().whenComplete(() =>
Navigator.of(context).pushReplacement(
PageTransition(
type: PageTransitionType.fade,
duration: const Duration(milliseconds: 1800),
child: const OnboardingScreen()
)
));
}
)
)
);
}
}
You can check the shared preference value in the Splash Screen and redirect the user to the OnBoardingScreen or LandingScreen.
import 'package:custom_form_field/src/form_screen.dart';
import 'package:flutter/material.dart';
import 'package:lottie/lottie.dart';
import 'package:shared_preferences/shared_preferences.dart';
class SplashScreen extends StatefulWidget {
const SplashScreen({Key? key}) : super(key: key);
#override
_SplashScreenState createState() => _SplashScreenState();
}
class _SplashScreenState extends State<SplashScreen>
with TickerProviderStateMixin {
late AnimationController _screenController;
#override
void initState() {
super.initState();
_screenController = AnimationController(vsync: this);
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
height: double.infinity,
width: double.infinity,
child: Lottie.asset('assets/lottie/splashScreen.lottie.json',
fit: BoxFit.fill,
controller: _screenController, onLoaded: (composition) {
_screenController
..duration = composition.duration
..forward().whenComplete(() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
// check shared preference and show particular screen
});
})));
}
}
You can check the shared preference value at initState and do the logic after animation complete as well. Also you can check login state from shared preference here and show login page if needed.
Make a global variable :
Global.dart
library my_prj.globals;
bool newUser = true;
main.dart
globals.newUser == true ? LandingPage() : LoginPage()
signup.dart
Here i am passing the variable
globals.newUser = false;
along with Username or Password fields.
After then your value will be permanently set false until and unless you make a change on it.

How to show updated list in shared preferences on UI - Flutter

I am making an app in a flutter in which I can select the contacts from phone book and saving them in shared preferences. No problem in data saving and retrieving but i m struggling with showing the updated list on my UI. It is showing the contacts list but every time I click on Load button it duplicates the list and showing 2 lists , 1 previous and other updated .
how can i show just updated list on UI ?
here is my code:
import 'package:contacts_test/select_contacts.dart';
import 'package:contacts_test/shared_pref.dart';
import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'dart:convert';
import 'contact_model.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return const MaterialApp(
title: 'Flutter Demo',
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({Key? key}) : super(key: key);
#override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
SharedPref sharedPref = SharedPref();
ContactModel modelLoad = ContactModel(displayName: 'saniya' , phoneNumber: '324235 ');
List _list = [];
#override
initState() {
super.initState();
// Add listeners to this clas
// loadSharedPrefs();
}
loadSharedPrefs() async {
try {
print('in load shared pref-- getting keys ');
final prefs = await SharedPreferences.getInstance();
final keys = prefs.getKeys();
print('now load shared pref ');
for (String key in keys) {
ContactModel user = ContactModel.fromJson(await sharedPref.read(key));
_list.add(user);
}
print('done load shared pref ');
}
catch (Excepetion) {
}
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text("contacts "),
),
body: Builder(
builder: (context) {
return Column(children: [
RaisedButton(
onPressed: () {
Navigator.push(
context, MaterialPageRoute(builder: (context) => Plugin1()));
},
child: const Text('fluttercontactpicker - plugin1'),
),
RaisedButton(
onPressed: () async {
await loadSharedPrefs();
},
child: Text('Load', style: TextStyle(fontSize: 20)),
),
Expanded(
child: _list.isNotEmpty ?
ListView.builder(
shrinkWrap: true,
itemCount: _list.length,
itemBuilder: (context, position) {
return ListTile(
leading: Icon(Icons.contacts),
title: Text(
_list[position].displayName.toString()
),
trailing: Icon(Icons.delete));
},
) : Center(child: Text('No list items to show')),
),
]);
}
),
);
}
}
Your loadSharedPrefs(); function adds each contact to the list you show. Every time you press the button, the same elements are added again to the list. There are multiple ways to avoid that. You can: empty the list before filling it, you can write a for loop to loop over the length of the incoming contacts and for each to add it to the list by always starting from index 0. In case you use some kind of replacement or removing method, make sure you call setState(()=> { });
Base on the answer, here is a possible solution:
import 'package:contacts_test/select_contacts.dart';
import 'package:contacts_test/shared_pref.dart';
import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'dart:convert';
import 'contact_model.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return const MaterialApp(
title: 'Flutter Demo',
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({Key? key}) : super(key: key);
#override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
SharedPref sharedPref = SharedPref();
ContactModel modelLoad = ContactModel(displayName: 'saniya' , phoneNumber: '324235 ');
List _list = [];
#override
initState() {
super.initState();
// Add listeners to this clas
// loadSharedPrefs();
}
loadSharedPrefs() async {
try {
print('in load shared pref-- getting keys ');
final prefs = await SharedPreferences.getInstance();
final keys = prefs.getKeys();
print('now load shared pref ');
var newList = [];
for (String key in keys) {
ContactModel user = ContactModel.fromJson(await sharedPref.read(key));
newList.add(user);
}
setState(()=> { _list = newList; });
print('done load shared pref ');
}
catch (Excepetion) {
}
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text("contacts "),
),
body: Builder(
builder: (context) {
return Column(children: [
RaisedButton(
onPressed: () {
Navigator.push(
context, MaterialPageRoute(builder: (context) => Plugin1()));
},
child: const Text('fluttercontactpicker - plugin1'),
),
RaisedButton(
onPressed: () async {
await loadSharedPrefs();
},
child: Text('Load', style: TextStyle(fontSize: 20)),
),
Expanded(
child: _list.isNotEmpty ?
ListView.builder(
shrinkWrap: true,
itemCount: _list.length,
itemBuilder: (context, position) {
return ListTile(
leading: Icon(Icons.contacts),
title: Text(
_list[position].displayName.toString()
),
trailing: Icon(Icons.delete));
},
) : Center(child: Text('No list items to show')),
),
]);
}
),
);
}
}

How to solve Shared Preferences not working in flutter?

I'm using Shared Preferences in flutter , but it not working with me in vs code and andriod studio , after adding dependencies and import the package then try the app nothing happen when clicking on the button which it do the function.
------- this my code in home page --------
import 'package:flutter/material.dart';
import 'package:flutter_application_2/another_screen.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'another_screen.dart';
void main() => runApp(const MyApp());
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Shared Preference',
theme: ThemeData(primarySwatch: Colors.blue),
home: const MyHomePage(title: 'Shared Preference'),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({Key? key, required this.title}) : super(key: key);
final String title;
#override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
#override
void initState() {
super.initState();
setData();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: ElevatedButton(
child: const Text('Go Another Screen'),
onPressed: () {
Navigator.of(context).push(MaterialPageRoute(
builder: (_) => const AnotherScreen(),
));
},
),
),
);
}
setData() async {
SharedPreferences _pref = await SharedPreferences.getInstance();
_pref.setString('name', 'Rady');
_pref.setInt('age', 19);
_pref.setString('university', 'Rady');
_pref.setInt('height', 19);
_pref.setStringList('skills', ['Dart', 'Flutter']);
}
}
----- the second page ------
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';
class AnotherScreen extends StatefulWidget {
const AnotherScreen({Key? key}) : super(key: key);
#override
State<StatefulWidget> createState() => AnotherScreenState();
}
class AnotherScreenState extends State<AnotherScreen> {
String _name = '';
int? _age;
String _university = '';
int? _height;
List<String> _skills = ['', ''];
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Info Screen'),
),
body: DefaultTextStyle(
style: const TextStyle(
fontSize: 30, fontWeight: FontWeight.bold, color: Colors.black),
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text('Name : $_name'),
Text('Age : $_age'),
Text('University : $_university'),
Text('Height : $_height'),
Text('Skill1 : ${_skills[0]}'),
Text('Skill2 : ${_skills[1]}'),
ElevatedButton(
child: const Text('Get Data'),
onPressed: () async {
await getData();
},
)
],
),
),
),
);
}
getData() async {
SharedPreferences _pref = await SharedPreferences.getInstance();
setState(() {
_name = _pref.getString('name')!;
_age = _pref.getInt('age');
_university = _pref.getString('university')!;
_height = _pref.getInt('height');
_skills = _pref.getStringList('skills')!;
});
}
}
Storing Data in shared preferences requires the await keyword
SharedPreferences _prefs = await SharedPreferences.getInstance();
await _prefs.setString('token', newToken);

Using Flutter and Dart, how can I get this Future to work?

I know that there are other ways of achieving this, but I want to use a Future via initState() to obtain a List using SharedPreferences. The following illustrates what I want to achieve, but it does not work as required, because the Future returns immediately before completing the task.
How should this be structured?
import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';
class _MyHomePageState extends State<MyHomePage> {
SharedPreferences _prefs;
String _sMessage = "No response from getting params";
List<String> _lsCategories;
#override
void initState() {
super.initState();
_initPreferences().then((_) {
try {
_lsCategories = _prefs.getStringList("categories") ?? [];
debugPrint("Categories = $_lsCategories");
_sMessage = "Categories loaded OK";
} catch (vError) {
_sMessage = ("Error loading categories = $vError");
}
setState(() {});
});
}
Future<void> _initPreferences() async {
SharedPreferences.getInstance().then((prefs) {
_prefs = prefs;
debugPrint("Preferences initialized OK");
}).catchError((vError) {
debugPrint("Error initializing preferences = ${vError.toString()}");
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(_sMessage,
style: TextStyle(
color: Colors.red[500],
fontWeight: FontWeight.bold,
fontSize: 20)),
],
),
),
);
}
}
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Future Test',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: "Flutter Future Test"),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
Change your _initPreferences method to the following:
Future<void> _initPreferences() async {
try {
final prefs = await SharedPreferences.getInstance();
_prefs = prefs;
debugPrint("Preferences initialized OK");
} catch (e) {
debugPrint("Error initializing preferences = ${e.toString()}");
}
}
The issue is that when using .then() on a Future you are not waiting for that future to finish, using await does wait.
Try it.
Future<void> _initPreferences() async {
_prefs = await SharedPreferences.getInstance().catchError((vError) {
debugPrint("Error initializing preferences = ${vError.toString()}");
};
debugPrint("Preferences initialized OK");
}