如何在Flutter中以编程方式更改应用程序语言?

10

目前,我正在使用flutter_localizations来翻译应用程序中的字符串。它工作得非常好,但需要能够通过按按钮或从下拉列表中选择语言来从应用程序的设置中切换本地化。对于这个应用程序,使用了BLoC设计模式。

请问你能否提供任何潜在解决该问题的建议?谢谢!


https://www.youtube.com/watch?v=lDfbbTvq4qM - Dean Villamia
2
@DeanVillamia 那并没有帮助。我已经实现了本地化。当我切换系统语言时,它会更改应用程序的语言。然而,我需要能够通过按按钮或与UI交互来在应用程序中执行此操作。 - Zuberu
好的,所以这是一个状态管理问题,只需在更改下拉列表时重新构建小部件即可。抱歉,我对bloc不太熟悉,因为我使用provider->changenotifier。 - Dean Villamia
@DeanVillamia,问题并不完全与状态管理有关。重建小部件是没有帮助的,因为我还没有对语言做任何处理。我有一个下拉菜单,但是如果要忽略系统语言更改应用程序语言,应该怎么做呢? - Zuberu
1
获取系统语言,然后将其保存到一个变量中,以便您可以操作。https://dev59.com/QFUL5IYBdhLWcg3wDUa2 - Dean Villamia
1个回答

7

针对未来的读者,以下是如何实现此操作:

LocaleMaterialApp 小部件内的 localeResolutionCallback 函数返回的结果定义。

在我的情况下,我将 final Locale defaultValue; 传递给我的应用程序根目录,即树中的第一个小部件(在 runApp() 中声明)。

此时,我只需进行以下验证:

import 'package:flutter/material.dart';
import 'package:flutter_localizations/flutter_localizations.dart';

import 'package:intl/intl.dart';

import '../../localization.dart';
import '../views/home_view.dart';

class App extends StatelessWidget {
  App({Key key, this.defaultLanguage}) : super(key: key);
  final Locale defaultLanguage;

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: HomeView(),
      localizationsDelegates: [
        AppLocalization.delegate,
        GlobalMaterialLocalizations.delegate,
        GlobalCupertinoLocalizations.delegate,
        GlobalWidgetsLocalizations.delegate,
      ],
      supportedLocales: [
        const Locale('en', null),
        const Locale('pl', null),
      ],
      localeResolutionCallback: (locale, supportedLocales) {
        if (defaultLanguage != null) {
          Intl.defaultLocale = defaultLanguage.toLanguageTag();
          return defaultLanguage;
        }
        if (locale == null) {
          Intl.defaultLocale = supportedLocales.first.toLanguageTag();
          return supportedLocales.first;
        }
        for (var supportedLocale in supportedLocales) {
          if (supportedLocale.languageCode == locale.languageCode) {
            Intl.defaultLocale = supportedLocale.toLanguageTag();
            return supportedLocale;
          }
        }
        Intl.defaultLocale = supportedLocales.first.toLanguageTag();
        return supportedLocales.first;
      },
    );
  }
}


如果 bloc 上一级传递了 defaultLanguage,则将在应用程序中使用它,否则进行标准验证以从设备中获取区域设置。
请记住,您可能需要通过验证 defaultLanguage 变量是否是受支持的语言环境来保护检查。 在我的情况下,已经处理了这个问题,所以我不需要担心。

那我们需要将整个 MaterialApp 组件用某种 LocalizationBloc 进行包装,对吗? - Zuberu
1
defaultLanguage 改变时,localeResolutionCallback 是否会被重新执行? - Canastro
@Zuberu 是的,那是一个选项。在我的应用程序中,我通过提供程序处理默认值。 - Breno Teodoro
@Canastro 是的。更改设备语言设置也会执行回调函数。 - Breno Teodoro

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接