在Flutter中如何通过JSON文件实现应用语言切换?
Flutter基于给定JSON结构实现多语言切换的实现方案
第一步:预处理资源与配置
- 首先补全JSON中
label_value的对应翻译值,比如法语场景下"label_value": "Nom du patient",补全后将JSON文件存放在项目assets/i18n/language_config.json路径下 - 在
pubspec.yaml中声明资源路径和依赖:
dependencies: flutter: sdk: flutter flutter_localizations: sdk: flutter shared_preferences: ^2.2.2 # 用于持久化用户选择的语言 flutter: assets: - assets/i18n/
第二步:实现本地化核心类
先将输入的扁平化JSON结构解析为按语言短码分类的翻译映射,再实现本地化委托逻辑:
import 'dart:convert'; import 'package:flutter/services.dart'; import 'package:flutter/material.dart'; import 'package:shared_preferences/shared_preferences.dart'; class AppLocalizations { final Locale locale; // 存储所有语言的翻译映射:key为语言短码,value为对应翻译键值对 static Map<String, Map<String, String>> _localizedValues = {}; // 存储当前生效的翻译键值对 Map<String, String> _currentLocalizedValues = {}; // 支持的语言列表 static List<Locale> supportedLocales = []; // 默认语言 static Locale? defaultLocale; AppLocalizations(this.locale); // 方便在组件中调用的方法 static AppLocalizations of(BuildContext context) { return Localizations.of<AppLocalizations>(context, AppLocalizations)!; } // 加载JSON资源并解析分组 static Future<void> loadConfig() async { String jsonString = await rootBundle.loadString('assets/i18n/language_config.json'); List<dynamic> jsonList = json.decode(jsonString); Map<String, Map<String, String>> tempMap = {}; Set<Locale> tempLocales = {}; Locale? tempDefaultLocale; for (var item in jsonList) { String shortCode = item['language_short_code'].toLowerCase(); String key = item['label_key']; String? value = item['label_value']; int isDefault = item['language_is_default']; // 初始化当前语言的映射 if (!tempMap.containsKey(shortCode)) { tempMap[shortCode] = {}; Locale locale = Locale(shortCode); tempLocales.add(locale); if (isDefault == 1) { tempDefaultLocale = locale; } } if (value != null) { tempMap[shortCode]![key] = value; } } _localizedValues = tempMap; supportedLocales = tempLocales.toList(); defaultLocale = tempDefaultLocale ?? supportedLocales.first; } // 加载当前语言的翻译 Future<bool> load() async { _currentLocalizedValues = _localizedValues[locale.languageCode] ?? {}; return true; } // 翻译方法,传入label_key返回对应翻译,不存在则返回原key String translate(String key) { return _currentLocalizedValues[key] ?? key; } // 切换语言的方法 static Future<void> changeLanguage(BuildContext context, Locale newLocale) async { SharedPreferences prefs = await SharedPreferences.getInstance(); await prefs.setString('selected_language', newLocale.languageCode); // 重建应用应用新语言 MyApp.of(context)?.setLocale(newLocale); } // 获取上次保存的语言 static Future<Locale?> getSavedLocale() async { SharedPreferences prefs = await SharedPreferences.getInstance(); String? code = prefs.getString('selected_language'); if (code == null) return null; return Locale(code); } } // 本地化委托 class AppLocalizationsDelegate extends LocalizationsDelegate<AppLocalizations> { final Locale? overriddenLocale; const AppLocalizationsDelegate({this.overriddenLocale}); @override bool isSupported(Locale locale) { return AppLocalizations.supportedLocales.any((e) => e.languageCode == locale.languageCode); } @override Future<AppLocalizations> load(Locale locale) async { AppLocalizations localizations = AppLocalizations(overriddenLocale ?? locale); await localizations.load(); return localizations; } @override bool shouldReload(AppLocalizationsDelegate old) => overriddenLocale != old.overriddenLocale; }
第三步:配置根组件
将根组件改为StatefulWidget支持动态更新Locale:
void main() async { WidgetsFlutterBinding.ensureInitialized(); // 预先加载语言配置 await AppLocalizations.loadConfig(); // 获取上次保存的语言 Locale? savedLocale = await AppLocalizations.getSavedLocale(); runApp(MyApp(initialLocale: savedLocale)); } class MyApp extends StatefulWidget { final Locale? initialLocale; const MyApp({super.key, this.initialLocale}); // 提供全局调用的方法更新Locale static MyAppState? of(BuildContext context) => context.findAncestorStateOfType<MyAppState>(); @override State<MyApp> createState() => MyAppState(); } class MyAppState extends State<MyApp> { Locale? _locale; void setLocale(Locale locale) { setState(() { _locale = locale; }); } @override void initState() { super.initState(); _locale = widget.initialLocale; } @override Widget build(BuildContext context) { return MaterialApp( title: '多语言Demo', locale: _locale, localizationsDelegates: const [ AppLocalizationsDelegate(), GlobalMaterialLocalizations.delegate, GlobalWidgetsLocalizations.delegate, GlobalCupertinoLocalizations.delegate, ], supportedLocales: AppLocalizations.supportedLocales, home: const HomePage(), ); } }
第四步:业务中使用
翻译调用示例
// 会自动根据当前语言返回对应翻译 Text(AppLocalizations.of(context).translate('Patient Name')) Text(AppLocalizations.of(context).translate('Doctor Id'))
切换语言示例
ElevatedButton( onPressed: () { AppLocalizations.changeLanguage(context, const Locale('fr')); }, child: const Text('切换为法语'), )
内容的提问来源于stack exchange,提问作者Nilrajsinh Vaghela
相关产品推荐
相关产品推荐

