Flutter 手把手国际化

1.导入依赖

  flutter:
    sdk: flutter
  flutter_localizations:
    sdk: flutter
  intl: any

2.安装插件Flutter Intl

Android Studio > File > Settings > Plugins 搜索Flutter Intl
并安装和重启Android Studio生效

3.通过插件初始化并配置语言

Android Studio > Tools > Flutter Intl > lnitialize for the Project
Flutter 手把手国际化_第1张图片
初始化后插件会自动创建
l10n.dart 语言管理类
messages_all.dart 语言管理类
messages_en.dart 英文
intl_en.arb 英文数据
路径为:
lib/generated/l10n.dart
lib/generated/intl/messages_all.dart
lib/generated/intl/messages_en.dart
lib/l10n/intl_en.arb

由此可知 插件只生成了英文版,所以我们需要手动加入中文配置

3.1配置中文

Android Studio > Tools > Flutter Intl > Add Locale 并输入zh
Flutter 手把手国际化_第2张图片
Flutter 手把手国际化_第3张图片
之后插件会生成对应的中文配置文件:
lib/generated/intl/messages_zh.dart
lib/l10n/intl_zh.arb

目前语言相关的文件已生成完,如下图
Flutter 手把手国际化_第4张图片
文件生成完了,接下来就是把中英文插入相应的位置了,
intl_zh.arb 和 intl_en.arb 分别代表中文和英文的语言数据,所以只需要修改它俩即可,其他文件会根据数据自动配置

3.2 加入语言数据

intl_zh.arb 和 intl_en.arb 是以json结构配置的,所以我们配置如下

lib/l10n/intl_zh.arb

{
  "str_download": "应用下载",
  "str_lang": "语言",
  "str_update": "检测更新",
  "str_about": "关于我们"
}

lib/l10n/intl_en.arb

{
  "str_download": "Application Download",
  "str_lang": "Language",
  "str_update": "Detect updates",
  "str_about": "About us"
}

语言配置好了,接下来就是怎么引用它们了。

4.使用国际化语言

4.1 页面引用语言字段

  _updateLang() async {
    AppLocalizationDelegate delegate = const AppLocalizationDelegate();
    //获取当前系统语言
    Locale myLocale = Localizations.localeOf(context);
    //根据当前语言获取对应的语言数据
    lang = await delegate.load(myLocale);
    //获取字段
    var update = lang.str_update;
    var about = lang.str_about;
  }

页面里面使用完整代码如下:

class MyPage extends StatefulWidget {
  const MyPage({super.key});

  @override
  State<StatefulWidget> createState() => _MyPageState();
}

class _MyPageState extends State<MyPage> {
  @override
  void initState() {
    super.initState();
  }

  late S lang;

  _updateLang() async {
    AppLocalizationDelegate delegate = const AppLocalizationDelegate();
    //获取当前系统语言
    Locale myLocale = Localizations.localeOf(context);
    //根据当前语言获取对应的语言数据
    lang = await delegate.load(myLocale);
  }

  @override
  Widget build(BuildContext context) {
    _updateLang();
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Colors.transparent,
        elevation: 0,
        title: Text("我的",
            style: TextStyle(
                fontSize: 30,
                color: AppColors.gray33,
                fontWeight: FontWeight.bold)),
      ),
      body: Container(
        child: Column(
          children: [
            Text(
              lang.str_download,
            ),
            Text(
              lang.str_lang,
            ),
            Text(
              lang.str_update,
            ),
            Text(
              lang.str_about,
            ),
          ],
        ),
      ),
    );
  }
}

这样页面里面的组件就引用到了语言管理类中的字段,但是还差一步初始化

4.2 main.dart中初始化语言配置

初始化插件生成的语言配置

      localizationsDelegates: const [
        AppLocalizationDelegate(),
        GlobalMaterialLocalizations.delegate,
        GlobalWidgetsLocalizations.delegate,
        GlobalCupertinoLocalizations.delegate,
      ],
      supportedLocales: const AppLocalizationDelegate().supportedLocales,
      locale: locale,

完整代码如下

void main() {
//默认为中文
  var locale = Locale.fromSubtags(languageCode: 'zh');
  runApp(MyApp(locale));
}

class MyApp extends StatelessWidget {
  final Locale locale;

  const MyApp(this.locale, {super.key});

  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(primarySwatch: Colors.blue, primaryColor: Colors.white),
      home: const MyHomePage(title: 'Flutter Demo Home Page'),
      routes: {
        MyRouter.DOWNLOAD_PAGE: (context) => DownLoadPage(),
        MyRouter.LANG_PAGE: (context) => LangPage(),
      },
//初始化语言配置
      localizationsDelegates: const [
        AppLocalizationDelegate(),
        GlobalMaterialLocalizations.delegate,
        GlobalWidgetsLocalizations.delegate,
        GlobalCupertinoLocalizations.delegate,
      ],
      supportedLocales: const AppLocalizationDelegate().supportedLocales,
      locale: locale,
    );
  }
}

这样语言就都配置好了,切换语言只需要调用
runApp(MyApp(locale))
传入对应语言参数即可。

5.切换语言

切换中文:

  var locale = Locale.fromSubtags(languageCode: 'zh');
  runApp(MyApp(locale));

切换英文:

var locale = Locale.fromSubtags(languageCode: 'en');
 runApp(MyApp(locale));

完整页面代码如下:

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

  //切换语言
  changeLang(Locale locale) {
    runApp(MyApp(locale));
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: BaseAppBar("语言"),
        body: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            InkWell(
              onTap: () {
                var locale = Locale.fromSubtags(languageCode: BaseData.ZH);
                changeLang(locale);
                SPUtils.setLangCode(BaseData.ZH);
                Navigator.pop(context);
              },
              child: Container(
                padding: EdgeInsets.only(left: 16),
                height: 60,
                child: Align(
                  alignment: Alignment.centerLeft,
                  child: Text(
                    "简体中文",
                    style: TextStyle(fontSize: 16, color: AppColors.gray33),
                  ),
                ),
              ),
            ),
            Container(
              margin: EdgeInsets.only(left: 16),
              height: 0.5,
              color: AppColors.line,
            ),
            InkWell(
              onTap: () {
                var locale = Locale.fromSubtags(languageCode: BaseData.EN);
                changeLang(locale);
                SPUtils.setLangCode(BaseData.EN);
                Navigator.pop(context);
              },
              child: Container(
                padding: EdgeInsets.only(left: 16),
                height: 60,
                child: Align(
                  alignment: Alignment.centerLeft,
                  child: Text(
                    "English",
                    style: TextStyle(fontSize: 16, color: AppColors.gray33),
                  ),
                ),
              ),
            ),
            Container(
              margin: EdgeInsets.only(left: 16),
              height: 0.5,
              color: AppColors.line,
            ),
          ],
        ));
  }
}

class BaseData{
  static const String ZH = 'zh';
  static const String EN = 'en';
}

这样就实现了在 语言设置 页面进行语言切换了,但是重启app后语言又还原成中文了,所以采用shared_preferences库保存上一次语言

6.重启APP 恢复最近设置的语言

class SPUtils {
  static const String _LANG_KEY = "lang_key";

  static setLangCode(String langCode) async {
    var sp = await SharedPreferences.getInstance();
    sp.setString(_LANG_KEY, langCode);
  }

  static Future<String> getLangCode() async {
    var sp = await SharedPreferences.getInstance();
    return sp.getString(_LANG_KEY) ?? BaseData.ZH;
  }
}

在设置页面设置完成后保存语言类型

    SPUtils.setLangCode(BaseData.ZH);

在App重启的时候获取数据并且设置,所以修改后的main.dart如下:

void main() async {
  // makes sure plugins are initialized 确保Flutter应用程序的绑定已经初始化完成
  WidgetsFlutterBinding.ensureInitialized();
  //执行异步获取
  var langCode = await SPUtils.getLangCode();
  var locale = Locale.fromSubtags(languageCode: langCode);
  runApp(MyApp(locale));
}

class MyApp extends StatelessWidget {
  final Locale locale;

  const MyApp(this.locale, {super.key});

  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(primarySwatch: Colors.blue, primaryColor: Colors.white),
      home: const MyHomePage(title: 'Flutter Demo Home Page'),
      routes: {
        MyRouter.DOWNLOAD_PAGE: (context) => DownLoadPage(),
        MyRouter.LANG_PAGE: (context) => LangPage(),
      },
      localizationsDelegates: const [
        AppLocalizationDelegate(),
        GlobalMaterialLocalizations.delegate,
        GlobalWidgetsLocalizations.delegate,
        GlobalCupertinoLocalizations.delegate,
      ],
      supportedLocales: const AppLocalizationDelegate().supportedLocales,
      locale: locale,
    );
  }
}

这里需要注意的是shared_preferences是异步获取的,所以要加上WidgetsFlutterBinding.ensureInitialized();

至此,语言切换完成。
最后附个版本:

sdks:
  dart: ">=3.1.0-185.0.dev <4.0.0"
  flutter: ">=3.7.0"

你可能感兴趣的:(Flutter,flutter)