Here I have implemented splash screen and in main.dart I assigned it as home:SplashScreen(); Here I have also implemented sharedPreferences now I am facing late initialisation error for:static late SharedPreferences pref; I can't understand how resolve it and where to declare pref variable import 'package:flutter/material.dart';
import 'package:onesignal_flutter/onesignal_flutter.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'View/LoginPage.dart';
import 'View/homePageAdmin.dart';
class SplashScreen extends StatefulWidget {
@override
State<SplashScreen> createState() => _SplashScreenState();
}
class SharedPrefService {
static late SharedPreferences pref;
static Future<void> init() async {
await SharedPrefService.init();
SharedPrefService.pref = await SharedPreferences.getInstance();
var usrEmail = pref.getString('email');
String usrname = pref.getString('username').toString();
}
}
class _SplashScreenState extends State<SplashScreen> {
String playerId = '';
var usrEmail = SharedPrefService.pref.getString('email');
String usrname = SharedPrefService.pref.getString('username').toString();
@override
void initState() async {
SharedPrefService.pref = await SharedPreferences.getInstance();
super.initState();
await SharedPrefService.init();
initPlatformState();
_navigateToHome();
}
Future<void> initPlatformState() async {
String usrname = SharedPrefService.pref.getString('username').toString();
OneSignal.shared.setAppId('e89acaa4-5388-4e3a-bd69-44d197bdcbd7');
// OneSignal.shared
// .promptUserForPushNotificationPermission()
// .then((accepted) {});
final status = await OneSignal.shared.getDeviceState();
final String? osUserID = status?.userId;
print('The player id from main.dart ...........${osUserID}');
// OneSignal.shared.setNotificationOpenedHandler(
// (OSNotificationOpenedResult result) async {
// var id1 = await result.notification.additionalData!["Docid"];
// final int docid = int.parse(id1).toInt();
// navigatorKey.currentState!.push(MaterialPageRoute(
// builder: (context) => DocumentsDetails(docid, usrname)));
// });
setState(() {
this.playerId = osUserID!;
});
print('this.playerid from main.dart ${this.playerId}');
}
_navigateToHome() async {
String pId = this.playerId;
await Future.delayed(Duration(milliseconds: 1500), () {});
Navigator.pushReplacement(
context,
MaterialPageRoute(
builder: (context) => usrEmail == null
? LoginPage()
: homePageAdmin(
pId,
usrname,
),
));
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Container(
child: Text(
'Splash Screen',
style: TextStyle(
fontSize: 25,
fontWeight: FontWeight.bold,
color: Colors.blueAccent),
),
),
),
);
}
}
CodePudding user response:
This error occurs when you use late
variable before its initialization.
Solution : making late
variable to nullable
variable, for example:
class SharedPrefService {
static SharedPreferences? pref; // nullable variable
static Future<void> init() async {
await SharedPrefService.init();
SharedPrefService.pref = await SharedPreferences.getInstance();
var usrEmail = pref?.getString('email');
String usrname = pref!.getString('username').toString();
}
}
CodePudding user response:
You cannot just make initState
async
and expect that to work. Yes, it will be async, but since it is still returning void
, it cannot be waited on. So, it will be called and then your program will continue without waiting for it.
You seem to have a Future
and not really an idea how to handle this inside a Flutter widget. I suggest getting a good overview:
What is a Future and how do I use it?
The solution is to use some kind of state management to handle the fact that you are doing something in the background. Your display cannot wait for it. It has to be displayed. The obvious solution is some kind of spinner or loading screen while you are waiting for the Future to resolve. There is a simple example of a FutureBuilder
in the link above, or you can use more powerful solutions. Personally, I prefer bloc, but there are many others, too.