internationalization - 如何将国际化对象传递给 Flutter 中的子控件

标签 internationalization dart flutter

刚开始使用 Flutter/dart,过渡到 PHP,并努力弄清楚如何将类传递给小部件。

我正在使用 Flutter 创建我的第一个 Android 和 iOS 应用程序。

我正在处理国际化,在我的初始构建页面上使用我拥有的国际化类一切正常。但是,当将它传递给另一个小部件时,我得到:

NoSuchMethodError: The getter textTitle was called on null.
Receiver: null
tried calling: textTitle

处理这个问题的最佳方法是什么?

flutter 医生

  [✓] Flutter (Channel beta, v0.1.5, on Mac OS X 10.13.3 17D47, locale en-US)
  [✓] Android toolchain - develop for Android devices (Android SDK 27.0.1)
  [✓] Android Studio (version 3.0)
  [✓] Connected devices (1 available)

本地化 Dart

class HnLocalizations{
        HnLocalizations(this.locale);

        final Locale locale;

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

        static Map<String, Map<String, String>> _localizedValues = {
            'en': {
                'btnLabelLoginS1': 'Login',
                'btnLabelRegisterS1': 'Sign Up'
            },
        ;

        String get s1ButtonLabelLogin =>
            _localizedValues[locale.languageCode]['btnLabelLoginS1'];

class HnLocalizationsDelegate extends LocalizationsDelegate<HnLocalizations> {
        const HnLocalizationsDelegate();

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

        @override
        Future<HnLocalizations> load(Locale locale) =>
            new SynchronousFuture<HnLocalizations>(new HnLocalizations(locale)); //HnLocalizations.load(locale);

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

主 Dart

void main() {

        runApp(new MaterialApp(
            localizationsDelegates: [
                const HnLocalizationsDelegate(),
                GlobalMaterialLocalizations.delegate,
                GlobalWidgetsLocalizations.delegate,
            ],
            supportedLocales: [
                const Locale('en', 'US'), /// Americans
                const Locale('en', 'GB') /// Brits
            ],
            title: 'HN',
            home: new EntryPage(),
        ));

    }

    class EntryPage extends StatelessWidget {

       final HnColors _hnColors = new HnColors();

        @override
        Widget build(BuildContext context) {

            return new Scaffold(
                appBar: new AppBar(
                    // !!!**** THIS WORKS AS EXPECTED ****!!!!
                    title: new Text(HnLocalizations.of(context).s1ButtonLabelLogin),
                    backgroundColor: _hnColors.transparent(),
                    elevation: 0.0,
                ),
                backgroundColor: _hnColors.accent(),
                body: new Container(
                    decoration: new BoxDecoration(
                        image: new DecorationImage(
                            image: new AssetImage("assets/Background_World.png"),
                            fit: BoxFit.fitWidth,
                        ),
                    ),
                    child: new PanelArea(),
                )
            );
        }
    }


    class PanelArea extends StatelessWidget {

        @override
        Widget build(BuildContext context) {

            HnColors _hnColors = new HnColors();

            return new Container(
                child: new Center(
                    child: new Container(
                        decoration: new BoxDecoration(
                            borderRadius: new BorderRadius.circular(15.0),
                            color: _hnColors.transparent()
                        ),
                        child: new Column(
                            children: [
                                new Image.asset('assets/Icon_Intro_login'),
                                new Text(
                                    // !!!**** ERROR IS HERE ****!!!!
                                    HnLocalizations.of(context).s1M1HeaderTitle,
                                    style: new TextStyle(
                                        color: _haillioColors.white()
                                    ),
                                ),

处理这个问题的最佳方法是什么?

更新:2018 年 3 月 11 日
我发现如果我将所有代码移动到 main.dart 文件中。所有本地化工作正常。但是,当我将我的小部件移到一个单独的 dart 文件中时,错误又回来了,即使所有代码都是相同的。

更新:2018 年 3 月 12 日 nicolás-carrasco a reference in this post 指出了正确的方向(谢谢)。该问题与已解决的进口有关 in this post here最终成为对我有用的解决方案。该示例在下面的答案中添加。

最佳答案

Nicolás Carrasco指出了与导致我出现问题的原因相关的解决方案by way of link to this post .

localization.dart 文件导入中,我有:

import 'package:hn/hnLocalization.dart';

main.dart 文件导入中我有:

import 'hnLocalization.dart';

这些与描述的不一样here

确保所有文件都使用相对路径与包导入解决了这个问题。区别在于我的文件而不是依赖项使用相对路径。那部分一开始被难住了。

现在我的 localization.dart 文件有以下内容。

import 'hnLocalization.dart'; // <--- Using relative Path

class PanelArea extends StatelessWidget {

        @override
        Widget build(BuildContext context) { ...

        child: new Column(
            children: [
                new Image.asset('assets/Icon_Intro_login'),

                // This Now Works --->
                new Text(HnLocalizations.of(context).s1M1HeaderTitle,
            ] 
       ...

现在一切都很好。

关于internationalization - 如何将国际化对象传递给 Flutter 中的子控件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49214934/

相关文章:

ios - Xcode 8 生成.strings 文件

iphone - 多语言 iOS 应用程序

ruby-on-rails - Rails - Twitter Bootstrap i18n - 验证

flutter - 为什么在Dart代码中使用dispose()方法?

ios - 使用 Flutter 包 firebase_messaging 的后台通知不适用于 iOS

android - 试图在 flutter 中创建一个没有 DRY 的 switchListTile

flutter - 什么时候 route.didPop(result) 在 Flutter Navigator 2.0 中等于 false

javascript - 字符串与javascript中的排序规则比较

json - 在 Dart 中使用 JsonObject 库解析 JSON 列表

dart - 带有 NestedScrollview 的 RefreshIndicator