FLUTTER学习笔记--多语言

文章详细介绍了如何在Flutter应用中实现国际化,包括设置`MaterialApp`的国际化代理,创建自定义的本地化类和代理,加载语言包,以及处理设备语言切换。示例代码展示了从pubspec.yaml配置到加载JSON语言资源的完整流程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


一、国际化

1.国际化:internationalization,简称i8n

  • 终端(手机)系统语言切换时,flutter应用的跟随切换

2.内容

  • 组件(Widget)国际化
  • 文本国际化(包括文本的顺序)
    • 自定义文本的国家化

3.组件

  • 在pubspec.yaml中引入flutter_localizations
    • 安装包:flutter pub get
  • 设置MaterialApp
    • import ‘package:flutter_localizations/flutter_localizations.dart’;
    • localizationsDelegates(指定哪些组件需要进行国际化)
    • supportedLocales(指定要支持哪些语言)

二、文本

1.创建本地化类

  • CustomLocalizations

2.创建本地化的代理

  • CustomLocalizationsDelegate extends LocalizationsDelegate<CustomLocalizations>
    • isSupported(当前本地化,是否在有效的语言范围内)
    • shouldReload(本地化重新构建时,是否调用load方法,加载本地化资源)
    • load(语言发生变更时,加载对应的本地化资源)

3.使用本地化类

  • CustomLocalizations.delegate

4.加载语言包

  • 判断当前语言
    • localeResolutionCallback
      • locale.languageCode(语言代码,例如,en、zh)
      • locale.countryCode(国家代码,例如:US、CN)
  • 设置语言包
    • 创建语言包
    • 在pubspec.yaml中配置语言资源
  • 异步加载语言包
    • 在CustomLocalizations中,添加loadJSON()方法
    • 在CustomLocalizationsDelegate中,调用CustomLocalizations的loadJSON()方法

三、代码

main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: HomePage(),
      //国际化
      localizationsDelegates: [
        //本地化代理
        CustomLocalizations.delegate,
        GlobalMaterialLocalizations.delegate,
        GlobalCupertinoLocalizations.delegate,
        GlobalWidgetsLocalizations.delegate,
      ],
      supportedLocales: const [
        Locale('en', 'US'),
        Locale('zh', 'CN'),


      ],
      localeResolutionCallback: (locale,supportedLocales) {
        print('deviceLocale:${locale}');
        print('languageCode:${locale?.languageCode}');
        print('countryCode:${locale?.countryCode}');
        for(var supportedLocale in supportedLocales){
          if(supportedLocale.languageCode==locale?.languageCode&&supportedLocale.countryCode==locale?.countryCode){
            return supportedLocale;
          }
        }
        return supportedLocales.first;
      },
    );
  }
}

class HomePage extends StatelessWidget {
  const HomePage({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        //title: const Text("learn1"),
        title: Text(Localizations.of(context, CustomLocalizations).t('title')),
        leading: Icon(Icons.menu),
        actions: [
          Icon(Icons.settings)
        ],
        elevation: 10.0,
        centerTitle: true,
      ),
      body: Texti18n(),
    );
  }
}

class Texti18n extends StatelessWidget {
  const Texti18n({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Center(
      child: Text(
        //'hello',
        //Localizations.of(context,CustomLocalizations).t("greet"),
        CustomLocalizations.of(context).t("greet").toString(),
        style: TextStyle(
          fontSize: 60
        ),
      ),
    );
  }
}

class CustomLocalizations{
  final Locale locale;

  CustomLocalizations(this.locale);

  // static final Map<String,Map<String,String>> _localizedValues={
  //   "en":{
  //     "title":"Home",
  //     "greet":"Hello"
  //   },
  //   "zh":{
  //     "title":"首页",
  //     "greet":"你好"
  //   },
  // };

  late Map<String,String> _localizedValues;

  Future<bool> loadJSON() async{
    String jsonString=await rootBundle.loadString('lang/${locale.languageCode}.json');
    Map<String,dynamic> jsonMap=json.decode(jsonString);

    _localizedValues=jsonMap.map((key, value) {
      return MapEntry(key, value.toString());
    });

    return true;
  }

  String? t(String key){
    //_localizedValues['zh']['title']
    // return _localizedValues[locale.languageCode]![key!];
    return _localizedValues[key];
  }

  static CustomLocalizations of(BuildContext context){
    return Localizations.of(context,CustomLocalizations);
  }

  static CustomLocalizationsDelegate delegate=CustomLocalizationsDelegate();
}

class CustomLocalizationsDelegate extends LocalizationsDelegate<CustomLocalizations>{
  @override
  bool isSupported(Locale locale) {
    return ["en","zh"].contains(locale.languageCode);
  }

  @override
  Future<CustomLocalizations> load(Locale locale) async{
   //return SynchronousFuture(CustomLocalizations(locale));
    CustomLocalizations localizations=CustomLocalizations(locale);
    await localizations.loadJSON();
    return localizations;
  }

  @override
  bool shouldReload(covariant LocalizationsDelegate<CustomLocalizations> old) {
    return false;
  }
}

四、效果

8e825154-5067-4898-9275-bef304ab3875.gif

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值