首页 文章

颤动:多语言应用程序 - 如何覆盖语言环境?

提问于
浏览
4

我按照官方Flutter页面中的解释(参见here)来使我的应用程序以不同的语言工作 .

根据文档,它检索用户的语言环境,这很好 .

现在让我们假设我的应用程序支持不同的语言(例如EN,FR,ES,...),并且用户可以选择其中一种语言来使用该应用程序(所选语言将不同于在手机的设置),我该怎么做到这一点?

我如何强制 application Locale和动态"reload"所有翻译?

Flutter页面没有解释这一点,我在文档中没有看到任何帮助我的东西......

这是当前的实现:

class Translations {
  Translations(this.locale);

  final Locale locale;

  static Translations of(BuildContext context){
    return Localizations.of<Translations>(context, Translations);
  }

  static Map<String, Map<String, String>> _localizedValues = {
    'en': {
      'title': 'Hello',
    },
    'fr': {
      'title': 'Bonjour',
    },
    'es': {
      'title': 'Hola',
    }
  };

  String text(String key){
    return _localizedValues[locale.languageCode][key] ?? '** ${key} not found';
  }
}

class TranslationsDelegate extends LocalizationsDelegate<Translations> {
  const TranslationsDelegate();

  @override
  bool isSupported(Locale locale) => ['en', 'fr','es'].contains(locale.languageCode);

  @override
  Future<Translations> load(Locale locale) {
    return new SynchronousFuture<Translations>(new Translations(locale));
  }

  @override
  bool shouldReload(TranslationsDelegate old) => false;
}

在main.dart中:

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      title: Translations.of(context).text('title'),
      theme: new ThemeData(
        primarySwatch: Colors.blue,
      ),
      localizationsDelegates: [
        const TranslationsDelegate(),
        GlobalMaterialLocalizations.delegate,
        GlobalWidgetsLocalizations.delegate,
      ],
      supportedLocales: [
        const Locale('en', ''), // English
        const Locale('fr', ''), // French
        const Locale('fr', ''), // French
      ],
        home: new LandingPage(),
    );
  }
}

非常感谢您的帮助 .

2 回答

  • 5

    这可以通过以下方式实现

    • 创建一个新的LocalizationsDelegate,它可以转换为单个区域设置,也可以根据参数完全延迟

    • 将基础应用程序(MyApp)转换为有状态窗口小部件,并将上面的新委托插入localizationsDelegates列表

    • 使用基于某个事件定位特定区域设置的新代理来管理基本应用程序(MyApp)状态

    1)的简单实现可能是:

    class SpecifiedLocalizationDelegate
        extends LocalizationsDelegate<Translations> {
      final Locale overriddenLocale;
    
      const SpecifiedLocalizationDelegate(this.overriddenLocale);
    
      @override
      bool isSupported(Locale locale) => overriddenLocale != null;
    
      @override
      Future<Translations> load(Locale locale) =>
          Translations.load(overriddenLocale);
    
      @override
      bool shouldReload(SpecifiedLocalizationDelegate old) => true;
    }
    

    接下来针对2)和3),将MyApp转换为有状态并包含新委托(最初只是推迟所有内容),以及一些事件处理程序,以使用指定新Locale的新委托来更改状态 .

    class MyApp extends StatefulWidget {
      @override
      _MyAppState createState() => new _MyAppState();
    }
    
    class _MyAppState extends State<MyApp> {
      SpecifiedLocalizationDelegate _localeOverrideDelegate;
    
      @override
      void initState() {
        super.initState();
        _localeOverrideDelegate = new SpecifiedLocalizationDelegate(null);
      }
    
      onLocaleChange(Locale l) {
        setState(() {
          _localeOverrideDelegate = new SpecifiedLocalizationDelegate(l);
        });
      }
    
      @override
      Widget build(BuildContext context) {
        return new MaterialApp(
          localizationsDelegates: [
            _localeOverrideDelegate,
            const TranslationsDelegate(),
            GlobalMaterialLocalizations.delegate,
            GlobalWidgetsLocalizations.delegate,
          ],
          supportedLocales: [
            const Locale('en', ''), // English
            const Locale('fr', ''), // French
          ],
          home: new LandingPage(onLocaleSwitch: onLocaleChange),
        );
      }
    }
    

    通过这些更改,在子窗口小部件中,您现在可以使用Translations.of(context).myLocalizedString来检索转换 .

    更完整的要点:https://gist.github.com/ilikerobots/474b414138f3f99150dbb3d0cc4cc721

  • 10

    要控制应用程序的区域设置,可以使用MaterialApp的locale属性:

    return MaterialApp(
      ...
      locale: _myLocal,
      ...
    );
    

    这与@ilikerobots StatefulWidget方法相结合,将为您提供所需的一切 .

相关问题