Flutter NoSuchMethodErro:方法'tr'在null上调用。接收者:null

时间:2020-07-20 08:36:13

标签: android-studio flutter localization language-translation

我是陌生人,我正在尝试本地化语言,但遇到错误

 localizationsDelegates: <LocalizationsDelegate>[
        GlobalMaterialLocalizations.delegate,
        GlobalWidgetsLocalizations.delegate,
        GlobalCupertinoLocalizations.delegate,


        EasyLocalizationDelegate(
          locale: data.locale ?? Locale('en', 'US'),
          path: 'resources/langs',
        ),
      ],
      supportedLocales: <Locale>[
        const Locale("en", "US"),
        const Locale("ar", "AR"),
      ],

在基本屏幕文件的行中获取错误The method 'tr' was called on null. Receiver: null Tried calling: tr("Click here to continue")

Text(
            AppLocalizations.of(context).tr('Click here to continue'),
//              "Click here to continue",
style: _textStyle,
),

enter image description here

我的加载函数是

Future<bool> load() async {
// Load the language JSON file from the "lang" folder
developer.log('file name', name: 'lang/${locale.languageCode}.json');
String jsonString =
await rootBundle.loadString('lang/${locale.languageCode}.json');
//await rootBundle.loadString('lang/${locale.languageCode}-${locale.countryCode}.json');
developer.log('file text', name: jsonString);
Map<String, dynamic> jsonMap = json.decode(jsonString);

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

return true;

}

目录文件为enter image description here

我还在我的pubspec.yaml资产中添加了打击代码

    - lang/
- resources/langs/en-US.json
- resources/langs/ar-AR.json

4 个答案:

答案 0 :(得分:2)

您是否遵循了Flutter页面上的完整示例?也许您只是想念一些东西!

这是我的配置,可以正常工作:

main.dart

localizationsDelegates: [
      AppLocalizations.delegate,
      GlobalWidgetsLocalizations.delegate,
      GlobalMaterialLocalizations.delegate,
    ],
    supportedLocales: [
      const Locale('en'),
      const Locale('it')
    ],

appLocalization.dart

import 'dart:convert';

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

class AppLocalizations{
  final Locale locale;

  AppLocalizations(this.locale);

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

  static const LocalizationsDelegate<AppLocalizations> delegate = _AppLocalizationsDelegate();

  Map<String,String> _localizedStrings;

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

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

  String translate(String key){
    return _localizedStrings[key];
  }

  
}

class _AppLocalizationsDelegate
    extends LocalizationsDelegate<AppLocalizations> {
  // This delegate instance will never change (it doesn't even have fields!)
  // It can provide a constant constructor.
  const _AppLocalizationsDelegate();

  @override
  bool isSupported(Locale locale) {
    // Include all of your supported language codes here
    return ['en', 'it'].contains(locale.languageCode);
  }

  @override
  Future<AppLocalizations> load(Locale locale) async {
    // AppLocalizations class is where the JSON loading actually runs
    AppLocalizations localizations = new AppLocalizations(locale);
    await localizations.load();
    return localizations;
  }

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

i18n文件夹中有两个文件,这两个文件位于pubspec.yaml中

  assets:
- i18n/it.json
- i18n/en.json

最后,像这样称呼它

AppLocalizations.of(context).translate('companyName'),

答案 1 :(得分:1)

对我来说,我发现我偶然添加了嵌套的MaterialApp小部件,该小部件在小部件的下方。因此,添加第二个MaterialApp小部件将覆盖我之前定义的内容。

答案 2 :(得分:0)

这个问题发生在我身上,是因为MaterialApp要求home:中指定的孩子是一个实际的单独的StatelessWidget,而不仅仅是直接嵌套。

如果该小部件直接嵌套在home:上,则无法在它们之间添加InheritedWidget,因此将没有Localizations小部件可从{{1}访问}。

答案 3 :(得分:0)

我遇到了同样的问题,我意识到问题出在拨打电话的页面上。 进行调用的页面有一个返回 MaterialApp 的小部件,在里面我有一个调用页面的按钮,并得到错误“方法 'tr' 被调用为 null”。 我将页面更改为:

Widget build(BuildContext context) {
    var data = EasyLocalizationProvider.of(context).data;
    return EasyLocalizationProvider(
      data: data,
      child: Scaffold(...

Scaffold里面有调用页面的按钮,没问题了。