I'm using translation files from server response and i want to change the translation after i select my preferred language and the page closes in language selection page, currently the translation works but until i reload the whole app on my device which is not ideal: here's language selection page:
class LanguageSelectionScreen extends StatelessWidget {
final bool navigateToAgreementPage;
LanguageSelectionScreen({this.navigateToAgreementPage = true});
Future<List<String>> _loadSelectedLanguages() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
return prefs.getStringList('selectedLanguages') ?? [];
}
Future<void> _saveSelectedLanguages(List<String> selectedLanguages) async {
SharedPreferences prefs = await SharedPreferences.getInstance();
await prefs.setStringList('selectedLanguages', selectedLanguages);
}
@override
Widget build(BuildContext context) {
return FutureBuilder<List<String>>(
future: _loadSelectedLanguages(),
builder: (BuildContext context, AsyncSnapshot<List<String>> snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return CircularProgressIndicator();
} else {
List<String> _selectedLanguages = snapshot.data ?? [];
return Scaffold(
appBar: AppBar(
title: Text('Select your Language').tr(),
),
body: Center(
child: Padding(
padding: EdgeInsets.only(top: 100),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Text("Choose your preferred languages"),
IconButton(
icon: Icon(Icons.add),
onPressed: () async {
String? selectedLanguage = await showDialog<String>(
context: context,
builder: (BuildContext context) {
return SimpleDialog(
title: Text('Select a language'),
children: <String>[
'English',
'Hindi',
'Arabic',
'French',
'Spanish',
'German',
'Italian',
'Russian',
'Japanese',
'Punjabi',
'Tamil',
'Gujarati',
].map((String value) {
return SimpleDialogOption(
child: Text(value),
onPressed: () {
Navigator.pop(context, value);
},
);
}).toList(),
);
},
);
if (selectedLanguage != null) {
_selectedLanguages.add(selectedLanguage);
_saveSelectedLanguages(_selectedLanguages);
changeLanguage(context, selectedLanguage);
}
},
),
..._selectedLanguages
.map((language) => Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
ElevatedButton(
style: ButtonStyle(
backgroundColor:
MaterialStateProperty.all<Color>(
Color(0xffF0E4D6)),
),
onPressed: () {
changeLanguage(context, language);
},
child: Text(
language,
style: TextStyle(color: Colors.black),
),
),
IconButton(
icon: Icon(Icons.delete, color: Colors.red),
onPressed: () {
if (_selectedLanguages.length > 1) {
_selectedLanguages.remove(language);
_saveSelectedLanguages(
_selectedLanguages);
} else {
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: Text('Warning'),
content: Text(
'At least one language must be selected.'),
actions: <Widget>[
TextButton(
child: Text('OK'),
onPressed: () {
Navigator.of(context).pop();
},
),
],
);
},
);
}
},
)
],
))
.toList(),
],
),
),
),
);
}
},
);
}
void changeLanguage(BuildContext context, String newValue) async {
Locale newLocale;
switch (newValue) {
case 'English':
newLocale = Locale('en');
break;
case 'Hindi':
newLocale = Locale('hi');
break;
case 'Arabic':
newLocale = Locale('ar');
break;
case 'French':
newLocale = Locale('fr');
break;
case 'Spanish':
newLocale = Locale('es');
break;
case 'German':
newLocale = Locale('de');
break;
case 'Italian':
newLocale = Locale('it');
break;
case 'Russian':
newLocale = Locale('ru');
break;
case 'Japanese':
newLocale = Locale('ja');
break;
case 'Punjabi':
newLocale = Locale('pa');
break;
case 'Tamil':
newLocale = Locale('ta');
break;
case 'Gujarati':
newLocale = Locale('gu');
break;
default:
newLocale = Locale('en');
}
SharedPreferences prefs = await SharedPreferences.getInstance();
await prefs.setString('languageCode', newLocale.languageCode);
context.setLocale(newLocale);
if (navigateToAgreementPage) {
Navigator.of(context).pushReplacement(
MaterialPageRoute(builder: (context) => AgreementPage()),
);
} else {
Navigator.of(context).pop();
}
}
}
here's my main.dart:
class CustomHttpAssetLoader extends AssetLoader {
@override
Future<Map<String, dynamic>?> load(String path, Locale locale) async {
String url =
'$path?filename=${locale.languageCode}.json&language=${locale.languageCode}';
final response = await http.get(Uri.parse(url));
if (response.statusCode == 200) {
return jsonDecode(response.body);
} else {
// load the English translations as default
final response =
await http.get(Uri.parse('$path?file=en&language=en'));
if (response.statusCode == 200) {
return jsonDecode(response.body);
} else {
throw Exception('Failed to load translation file');
}
}
}
}
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await EasyLocalization.ensureInitialized();
await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform);
FirebaseFirestore.instance.settings = Settings(persistenceEnabled: true);
await dotenv.load();
SharedPreferences prefs = await SharedPreferences.getInstance();
String languageCode = prefs.getString('languageCode') ?? 'en';
Locale locale = Locale(languageCode);
tz.initializeTimeZones();
runApp(
EasyLocalization(
supportedLocales: [
Locale('en'),
Locale('fr'),
Locale('hi'),
Locale('ar'),
Locale('es'),
Locale('de'),
Locale('it'),
Locale('ru'),
Locale('ja'),
Locale('pa'),
Locale('ta'),
Locale('gu'),
],
path:
'http://example/exp/get-language-translation-file',
assetLoader: CustomHttpAssetLoader(),
fallbackLocale: Locale('en', 'US'),
child: MyApp()),
);
}
class MyApp extends StatefulWidget {
const MyApp({
Key? key,
}) : super(key: key);
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
@override
void initState() {
super.initState();
}
@override
Widget build(BuildContext context) {
final Brightness brightness = MediaQuery.of(context).platformBrightness;
final bool isDarkMode = brightness == Brightness.dark;
return GetMaterialApp(
debugShowCheckedModeBanner: false,
localizationsDelegates: context.localizationDelegates,
supportedLocales: context.supportedLocales,
locale: context.locale,
theme: isDarkMode ? ThemeData.dark() : ThemeData.light(),
home: Material(
child: InkWell(
onTap: () {
HapticFeedback.heavyImpact();
},
child: SplashScreen(),
),
),
);
}
}
Please help me and thank you in advance
I've fixed the issue since I'm using GetMaterialApp
in my main.dart I have to use Get.updateLocale()
to inform GetMaterialApp
about the language change in my language selection page as well like this:
await context.setLocale(newLocale);
Get.updateLocale(newLocale);