Flutter 国际化(一) - 文字

363 阅读1分钟

Flutter Intl插件

完整代码

插件主页

安装Flutter Intl插件

在插件市场找到Flutter Intl,安装后,重新启动Android Studio

123465.png

初始化配置

点击下面操作

init.png

点击Initalize for the Project可以看到pubspec.yaml中最后一行添加了如下代码

flutter_intl:
  enabled: true

添加语言资源文件

点击Add Locale这里我们分别创建英文和简体中文两种语言,分别添加enzh_CN

QQ截图20230912230105.png

会自动生成两个arb文件,格式类似json,我们分别添加内容,这里的{d}代表占位符号,使用大括号包裹即可

intl_en.arb

{
  "hello": "Hello Flutter!",
  "click_times": "You have pushed the button this {d} times"
}

intl_zh_CN.arb

{
  "hello": "你好Flutter!",
  "click_times": "你已按了这个按钮{d}次"
}

在代码中使用

Text(S.current.hello),
Text(S.of(context).click_times(_counter)),

然后后Ctrl+s保存,插件就会帮我们自动创建和更新配置,我们看到插件会自动生成以下代码

QQ截图20230912231552.png

上面生成的代码引用找不到报错,打开pubspec.yaml,添加国际化支持,然后使用命令pub get

dependencies:
  flutter:
    sdk: flutter
  flutter_localizations:
    sdk: flutter

切换语言

配置Locale相关

LocaleChangeNotifier localeChangeNotifier = LocaleChangeNotifier();

class MyAppState extends State<MyApp> {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      home: const MyHomePage(title: 'Flutter Demo Home Page'),
      locale: localeChangeNotifier.locale,
      localeResolutionCallback: (Locale? locale, Iterable<Locale> supportedLocales) {
        if (localeChangeNotifier.locale == null) {
          localeChangeNotifier.init(supportedLocales.contains(locale!) ? locale : const Locale("en"));
        }
        return localeChangeNotifier.locale;
      },
      supportedLocales: S.delegate.supportedLocales,
      localizationsDelegates: const [
        GlobalMaterialLocalizations.delegate,
        GlobalWidgetsLocalizations.delegate,
        GlobalCupertinoLocalizations.delegate,
        S.delegate,
      ],
    );
  }

  @override
  void initState() {
    localeChangeNotifier.addListener(() {
      setState(() {});
    });
    super.initState();
  }

  @override
  void dispose() {
    localeChangeNotifier.dispose();
    super.dispose();
  }
}

监听Locale修改

这里定义了一个LocaleChangeNotifier监听语言变化更新

class LocaleChangeNotifier extends ChangeNotifier {
  Locale? _locale;

  Locale? get locale => _locale;

  void init(Locale locale) {
    _locale = locale;
  }

  void change(Locale locale) {
    if (_locale.toString() != locale.toString()) {
      _locale = locale;
      notifyListeners();
    }
  }
}

切换Locale

class IntlPage extends StatefulWidget {
  const IntlPage({super.key});

  @override
  State<IntlPage> createState() => _IntlPageState();
}

class _IntlPageState extends State<IntlPage> {
  int _counter = 0;

  void _incrementCounter() {
    setState(() {
      _counter++;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('IntlPage')),
      floatingActionButton: FloatingActionButton(
        onPressed: _incrementCounter,
        tooltip: 'Increment',
        child: const Icon(Icons.add),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Text(S.current.hello),
            Text(S.of(context).click_times(_counter)),
            Column(
              children: S.delegate.supportedLocales
                  .map((locale) => Row(
                        children: [
                          Radio(
                            value: locale.toString(),
                            onChanged: (value) {
                              localeChangeNotifier.change(locale);
                            },
                            groupValue: localeChangeNotifier.locale.toString(),
                          ),
                          Text(locale.toString()),
                        ],
                      ))
                  .toList(),
            ),
          ],
        ),
      ),
    );
  }
}

1694611719442.jpg1694611719437.jpg