【问题标题】:Best approach to null safe AppLocalization strings空安全 AppLocalization 字符串的最佳方法
【发布时间】:2021-04-15 20:09:27
【问题描述】:

问题

我正在使用 AppLocalizations.of(context).myString 在我的 null 安全颤振应用程序中国际化字符串。

我的 IDE 告诉我 AppLocalizations.of(context) 可以返回 null。处理这个问题的最佳方法是什么?有没有办法确保AppLocalizations.of(context) 永远不会返回 null?

目前,我采用以下方法:

AppLocalizations.of(context)?.myString ?? 'Fallback string'

完整的项目代码

Pubspec.yaml

name: Sample Intl Project
description: A sample project
publish_to: 'none'
version: 1.0.0+1

environment:
  sdk: ">=2.12.0-133.2.beta <3.0.0"

dependencies:
  flutter:
    sdk: flutter
  flutter_localizations:
    sdk: flutter
  intl: ^0.17.0-nullsafety.2

dev_dependencies:
  flutter_test:
    sdk: flutter

flutter:
  uses-material-design: true
  generate: true

l10n.yaml

arb-dir: lib/l10n
template-arb-file: app_en_US.arb
output-localization-file: app_localizations.dart

l10n/app_en_US.arb

{
  "helloWorld": "Hello World!",
  "@helloWorld": {
    "description": "Greeting"
}

l10n/app_en.arb

{
  "helloWorld": "Hello World!"
}

main.dart

import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';

void main() {
  runApp(App());
}

class App extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Sample App',
      localizationsDelegates: AppLocalizations.localizationsDelegates,
      supportedLocales: AppLocalizations.supportedLocales,
      home: Home()
    );
  }
}

class Home extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Center(
      child: Text(
        AppLocalizations.of(context)?.helloWorld ?? 'Hello World!'
      ),
    );
  }
}

【问题讨论】:

  • AppLocalizations 的包是从哪里来的?
  • 它是在你向 Flutter 应用添加国际化配置时自动生成的。请参阅docs,特别是第 6 步和第 7 步。
  • 能否请您提供更多代码,我没有出现此消息
  • 试试AppLocalizations.of(context).myString。您需要首先通过执行以下命令来选择 null 安全性:flutter channel beta; flutter upgrade in a terminal。

标签: flutter dart internationalization dart-null-safety


【解决方案1】:

如果您确定,AppLocalizations.of(context) 将始终返回 一个有效的AppLocalizations 实例(对于您的示例应用程序是正确的),您可以使用:

AppLocalizations.of(context)!.myString

! 运算符告诉 Dart,AppLocalizations.of(context) 永远不会返回 null 的作用类似于从可空的AppLocalizations? 转换为不可空的AppLocalizations

注意:如果AppLocalizations.of(context)在运行时返回null,那么AppLocalizations.of(context)!会抛出异常。

【讨论】:

    【解决方案2】:

    在 l10n.yaml 中添加这一行:

    nullable-getter: false
    

    【讨论】:

      【解决方案3】:

      正如评论中所说,我希望您尽可能多地分享您的代码、您的 pubpsec、您的 l10n.yaml 以及其他任何相关内容。

      在此之前我的建议是将依赖项中的 intl 从最新更新为:

      intl: ^0.17.0-nullsafety.2

      我认为 nullsafety 不会留给最终的开发人员,它很快就会成为标准,而不必考虑它。

      【讨论】:

      • 谢谢,我已经在使用intl: ^0.17.0-nullsafety.2,我已经分享了我的完整项目代码。
      【解决方案4】:

      看起来,您的应用始终期望来自AppLocalizations 文本的string 值。
      我建议确保 string 是空安全的,这应该可以解决您的问题。
      这是你可以使用的sn-ps。

      1. 定义字符串扩展名
      // a string extension
      extension MyStringExtentions on String {
        String nullSafeStr() =>
            (this == null || this.isEmpty || this == "null") ? "" : this;
      }
      
      // OR a static method
      //static String nullSafeStr(String source) => (source == null || source.isEmpty || source == "null") ? "" : source;
      
      

      现在您可以使用其中任何一个,请参阅使用新扩展的示例

      // .nullSafeStr() becomes available wherever you import the extension method 
      AppLocalizations.of(context).helloWorld.nullSafeStr()
      
      // the alternative way is to call the static method  
      .nullSafeStr(AppLocalizations.of(context).helloWorld);  
      

      【讨论】:

      • 需要使用.translate('key') 的文档在哪里?在official internationalizing Flutter guide。它不使用.translate('key')
      • 抱歉,这是我的错,我从我的应用程序中复制了 sn-p。我有一个实用程序,它抽象了 AppLocalizations 用法,我对所有键使用 .translate('key') 方法。我会更新我的答案
      • @AdamGriffiths 已经尝试过我的建议了吗?
      • 是的,但这不是一个很好的建议。首先AppLocalizations.of(context).helloWorld.nullSafeStr() 必须转为AppLocalizations.of(context)?.helloWorld.nullSafeStr()。其次,如果它实际上为 null,我们将返回一个空字符串,这会使 UI 看起来很奇怪。
      【解决方案5】:

      我认为您需要使用assert 来确保空值安全。这样可以确保其中的变量不为空。更多信息 (assert dart dcumentation)

      【讨论】:

      • 断言仅在开发中起作用,我需要一个生产就绪的解决方案。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-03-23
      • 1970-01-01
      • 1970-01-01
      • 2021-12-25
      • 1970-01-01
      • 2016-12-11
      相关资源
      最近更新 更多