空安全 AppLocalization 字符串的最佳方法

Best approach to null safe AppLocalization strings

问题

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

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

目前,我采用以下方法:

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!'
      ),
    );
  }
}

正如评论中所说,我会请你分享更多你的代码、你的 pubpsec、你的 l10n.yaml 以及尽可能多的其他相关内容。

到那时我的建议是将依赖项中的 intl 从最新更新为:

intl: ^0.17.0-nullsafety.2

我认为 nullsafety 不会留给最终开发者,它很快就会成为标准,而无需考虑它。

看起来,您的应用总是期望从 AppLocalizations 文本中获得 string 值。
我建议确保 string 是 null 安全的,这应该可以解决您的问题。
以下是您可以使用的片段。

  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);  

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

AppLocalizations.of(context)!.myString

! 运算符告诉 Dart,AppLocalizations.of(context) 永远不会 return null 并且就像从可为空的 AppLocalizations? 到不可为空的 AppLocalizations.

的强制转换

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

在l10n.yaml中添加这一行:

nullable-getter: false