'FlutterNativeSplash.removeAfter(initialisation) renders next screen before initialisation completes
I am using flutter_native_splash package and shared_preferneces to store my app data. I have the following code in my main.dart file.
import 'package:flutter/material.dart';
import 'package:flutter_native_splash/flutter_native_splash.dart';
import 'package:location/location.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'home_management.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
FlutterNativeSplash.removeAfter(initialization);
runApp(const MyApp());
}
void initialization(BuildContext context) async {
// Initialise shared preferences
SharedPreferences sharedPreferences = await SharedPreferences.getInstance();
// Initialise user location and store it in shared preferences
Location _location = Location();
bool? _serviceEnabled;
PermissionStatus? _permissionGranted;
LocationData? _locationData;
_serviceEnabled = await _location.serviceEnabled();
if (!_serviceEnabled) {
_serviceEnabled = await _location.requestService();
}
_permissionGranted = await _location.hasPermission();
if (_permissionGranted == PermissionStatus.denied) {
_permissionGranted = await _location.requestPermission();
}
_locationData = await _location.getLocation();
sharedPreferences.setDouble('latitude', _locationData.latitude!);
sharedPreferences.setDouble('longitude', _locationData.longitude!);
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
debugShowCheckedModeBanner: false,
theme: ThemeData(brightness: Brightness.light),
darkTheme: ThemeData(brightness: Brightness.dark),
themeMode: ThemeMode.dark,
home: const HomeManagement(),
);
}
}
I am using HomeManagement to manage my Pages with a bottom navigation bar, and the first page to load is RestaurantsMap() which looks as below.
import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';
class RestaurantsMap extends StatefulWidget {
const RestaurantsMap({Key? key}) : super(key: key);
@override
State<RestaurantsMap> createState() => _RestaurantsMapState();
}
class _RestaurantsMapState extends State<RestaurantsMap> {
late Future<SharedPreferences> sharedPreferences;
@override
void initState() {
sharedPreferences = SharedPreferences.getInstance();
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Restaurants Map'),
),
body: FutureBuilder(
future: sharedPreferences,
builder: (BuildContext context,
AsyncSnapshot<SharedPreferences> snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
print(snapshot.data!.getDouble('latitude'));
return const Center(
child: Text('Start building something awesome! 💪🏻'),
);
} else {
return Container();
}
}),
);
}
}
Whenever I am accessing the latitude in RestaurantsMap inside the FutureBuilder, I am getting a null printed by the following line of code:
print(snapshot.data!.getDouble('latitude'));
Using print statements inside the initialization() function after sharedPreferences.setDouble returns the data, so the only logical explanation is that I am accessing the getDouble('latitude') before it is getting set.
Any observations/solutions would be helpful.
Solution 1:[1]
For future viewers, if anyone faces the same issue, just update to the latest version for flutter_native_splash. An update has been released that gives more flexibility to make a call to remove the splash screen.
Here is the new readme - https://pub.dev/packages/flutter_native_splash#3-set-up-app-initialization-optional
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | imperial-lord |
