I am using a Flutter FutureBuilder
widget and SharedPreferences
, to wait for the preferences to be loaded before using them to get the language and pass them to child widgets.
Here is my code:
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:i18n_extension/i18n_widget.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'helpers/color.dart';
import 'pages/home.dart';
import '../constants.dart';
void main() {
runApp(
const ProviderScope(
child: MyApp(),
),
);
}
Future<SharedPreferences> getPrefs() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
return prefs;
}
Locale getLanguageSetting(SharedPreferences prefs) {
String? lang = prefs.getString('language');
if (LANGUAGES.contains(lang)) {
return Locale(lang, '');
}
return const Locale('en', '')
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return FutureBuilder(
future: getPrefs(),
builder: (context, snapshot) {
if (snapshot.hasData) {
return MaterialApp(
localizationsDelegates: const [
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
GlobalCupertinoLocalizations.delegate,
],
supportedLocales: const [
Locale('en', ''),
Locale('jp', ''),
],
home: I18n(
initialLocale: getLanguageSetting(snapshot.data),
child: HomeWidget(getPrefs: snapshot.data)), // to force locale to jp
);
} else {
return const Center(
child: CircularProgressIndicator(),
);
}
}
);
}
}
But I have trouble with the type of snapshot.data
: both the method and widget I'm passing it to send back a type error The argument type 'Object?' can't be assigned to the parameter type 'SharedPreferences'.
I thought snapshot.data
should be of type SharedPreferences
according to future: getPrefs()
, but it seems it's of type AsyncSnapshot<Object?>
.
Why? Should I cast snapshot.data
into a SharedPreferences
type (I'm not very comfortable with casting)? How can I do that?
CodePudding user response:
Define the type in snapshot as AsyncSnapshot<SharedPreferences> snapshot
. Then If you are running a null safe version change the type of sharedPreferences to SharedPreferences? in getLanguageSetting also.
import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';
void main() {
runApp(MyApp());
}
Future<SharedPreferences> getPrefs() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
return prefs;
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return FutureBuilder(
future: getPrefs(),
builder: (context, AsyncSnapshot<SharedPreferences?> snapshot) {
if (snapshot.hasData) {
print(snapshot.data.runtimeType);
getLanguageSetting(snapshot.data);
return MaterialApp(
localizationsDelegates: const [],
supportedLocales: const [
Locale('en', ''),
Locale('jp', ''),
],
home: Container(
color: Colors.red,
));
} else {
return const Center(
child: CircularProgressIndicator(),
);
}
});
}
}
void getLanguageSetting(SharedPreferences? prefs) {
print(prefs.runtimeType);
}