Flutter国际化插件interactive_i18n的使用

发布于 1周前 作者 sinazl 来自 Flutter

Flutter国际化插件interactive_i18n的使用

Flutter 包用于处理国际化。

特性

  • InteractiveLocalization 小部件用于给子小部件应用国际化的设置。它需要一个可用语言列表和一个语言更新时触发的函数。
  • Getter 翻译通过在字符串末尾添加一个点.t`来获取翻译后的值。
  • InteractiveI18nSelector 小部件允许用户选择语言。点击图标会展示一个包含可用语言的屏幕。onLanguageSelected 属性是一个当用户选择语言时触发的函数。

开始使用

在你的 pubspec.yaml 文件中添加依赖:

dependencies:
  interactive_i18n: ^1.0.2

使用

首先,你需要创建 JSON 文件以供翻译使用。可以参考以下示例:

示例文件路径

InteractiveLocalization

InteractiveLocalization 是一个包裹子小部件并应用国际化设置的小部件。它需要一个可用语言列表和一个语言更新时触发的函数。在这个例子中,InteractiveLocalization 小部件包裹了 Scaffold 小部件,并指定了可用语言和语言更新回调函数。

return InteractiveLocalization(
  availableLanguages: availableLanguages,
  languageUpdated: languageUpdated,
  localesPath: 'assets/locales/',
  child: Scaffold(
    ...
  ),
);

InteractiveI18nSelector

InteractiveI18nSelector 是一个小部件,可以让用户选择语言。它展示一个图标,点击后会显示一个包含可用语言的新屏幕。onLanguageSelected 属性是一个当用户选择语言时触发的函数。

InteractiveI18nSelector(
  iconSize: 50,
  onLanguageSelected: (language) {
    debugPrint('User picked language $language');
  },
),

Translation String Extension

.t 字符串扩展用于获取翻译后的字符串值。在这个例子中,字符串带有 .t 扩展以便进行翻译。

例如:

Text(
  'You have pushed the button this many times:'.t,
),

示例

完整示例见 这里

import 'package:flutter/material.dart';
import 'package:interactive_i18n/interactive_i18n.dart';
import 'package:provider/provider.dart';

void main() {
  runApp(const MyApp());
}

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

  [@override](/user/override)
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  bool _isDarkModeEnabled = false;

  void _toggleDarkMode() {
    setState(() {
      _isDarkModeEnabled = !_isDarkModeEnabled;
    });
  }

  [@override](/user/override)
  Widget build(BuildContext context) => MaterialApp(
        debugShowCheckedModeBanner: false,
        title: 'Flutter Demo',
        theme: ThemeData.light(),
        darkTheme: ThemeData.dark(),
        themeMode: _isDarkModeEnabled ? ThemeMode.dark : ThemeMode.light,
        home: MyHomePage(toggleDarkMode: _toggleDarkMode),
      );
}

class MyHomePage extends StatefulWidget {
  final VoidCallback toggleDarkMode;

  const MyHomePage({required this.toggleDarkMode, super.key});

  [@override](/user/override)
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  int _counter = 0;
  double _toolbarHeight = 30;
  bool _useDeviceLocale = true;
  bool _useSimCard = true;
  String _defaultLanguage = 'pt';
  bool textDescription = true;

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

  void _toggleUseDeviceLocale(bool value) {
    setState(() {
      _useDeviceLocale = value;
    });
  }

  void _toggleUseSimCard(bool value) {
    setState(() {
      _useSimCard = value;
    });
  }

  void _setDefaultLanguage(String language) {
    setState(() {
      _defaultLanguage = language;
    });
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    const List<String> availableLanguages = [
      'ar', 'cs', 'da', 'de', 'el', 'en', 'es', 'fi', 'fil', 'fr', 'he', 'hi', 'hu', 'id', 'it', 'ja', 'ko', 'no', 'nl', 'pl', 'pt', 'ru', 'sv', 'th', 'tr', 'uk', 'vi', 'zh'
    ];

    return InteractiveLocalization(
      availableLanguages: availableLanguages,
      languageUpdated: languageUpdated,
      localesPath: 'assets/locales/',
      useDeviceLocale: _useDeviceLocale,
      useSimCard: _useSimCard,
      defaultLanguage: _defaultLanguage,
      child: Scaffold(
        appBar: AppBar(
          toolbarHeight: _toolbarHeight,
          title: Text('Flutter Demo Home Page'.t),
          leading: IconButton(
            icon: Icon(
              Icons.brightness_6,
              color: Theme.of(context).appBarTheme.iconTheme?.color,
            ),
            onPressed: widget.toggleDarkMode,
          ),
          actions: [
            Container(
              margin: const EdgeInsets.only(right: 5),
              child: InteractiveI18nSelector(
                key: UniqueKey(),
                iconSize: 50,
                onLanguageSelected: (language) {
                  debugPrint('User picked language $language');
                },
                textDescription: textDescription,
              ),
            )
          ],
        ),
        body: Center(
          child: SingleChildScrollView(
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: [
                Container(
                  margin: const EdgeInsets.all(20),
                  child: Text(
                    'The purpose of this app is to show how to use the interactive_i18n package.'
                        .t,
                  ),
                ),
                Text('You have pushed the button this many times:'.t),
                Text(
                  '$_counter',
                  style: Theme.of(context).textTheme.headlineMedium,
                ),
                const SizedBox(height: 20),
                Text('Toolbar height'.t),
                Slider(
                  value: _toolbarHeight,
                  min: 30,
                  max: 100,
                  divisions: 7,
                  label: _toolbarHeight.round().toString(),
                  onChanged: (double value) {
                    setState(() {
                      _toolbarHeight = value;
                    });
                  },
                ),
                SwitchListTile(
                  title: Text('Text Description'.t),
                  value: textDescription,
                  onChanged: (bool value) {
                    setState(() {
                      textDescription = value;
                    });
                  },
                ),
                SwitchListTile(
                  title: Text('Use Device Locale'.t),
                  value: _useDeviceLocale,
                  onChanged: _toggleUseDeviceLocale,
                ),
                SwitchListTile(
                  title: Text('Use SIM Card Locale'.t),
                  value: _useSimCard,
                  onChanged: _toggleUseSimCard,
                ),
                Row(
                  children: [
                    Text('Default language:'.t),
                    DropdownButton<String>(
                      value: _defaultLanguage,
                      onChanged: (String? newValue) {
                        if (newValue != null) {
                          _setDefaultLanguage(newValue);
                        }
                      },
                      items: availableLanguages
                          .map<DropdownMenuItem<String>>((String language) => DropdownMenuItem<String>(
                                value: language,
                                child: Text(language),
                              ))
                          .toList(),
                    ),
                  ],
                ),
                LanguageProviderWidget(),
              ],
            ),
          ),
        ),
        floatingActionButton: FloatingActionButton(
          onPressed: _incrementCounter,
          tooltip: 'Increment',
          child: const Icon(Icons.add),
        ),
      ),
    );
  }

  void languageUpdated() {
    debugPrint('Set state');
    setState(() {});
  }
}

class LanguageProviderWidget extends StatelessWidget {
  [@override](/user/override)
  Widget build(BuildContext context) {
    final LanguageProvider languageProvider = Provider.of<LanguageProvider>(context);
    final List<String> languages = languageProvider.availableLanguages;
    final String currentLanguage = languageProvider.getLanguage();
    final String currentDeviceLanguage = languageProvider.getDeviceCurrentLanguage();
    final String currentSimCode = languageProvider.getSimCountryCode();
    final TextEditingController _deviceLanguageController = TextEditingController();

    return Container(
      margin: const EdgeInsets.all(20),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          Text('Current language: $currentLanguage'),
          Text('Language description: ${languageProvider.languageDescription}'),
          const SizedBox(height: 10),
          Text('Current device language: $currentDeviceLanguage'),
          // TextField to set the device language
          TextField(
            decoration: const InputDecoration(
              labelText: 'Set device language',
              hintText: 'en',
            ),
            onSubmitted: (String value) {
              languageProvider.setDeviceLanguage(value);
              languageProvider.refresh();
            },
            controller: _deviceLanguageController,
          ),
          MaterialButton(
            onPressed: () {
              languageProvider
                  .setDeviceLanguage(_deviceLanguageController.text);
              languageProvider.refresh();
            },
            child: const Text('Set device language'),
          ),
          const SizedBox(height: 10),
          Text('Current SIM code: $currentSimCode'),
          const SizedBox(height: 10),
          Text('Available languages: $languages'),
        ],
      ),
    );
  }
}

更多关于Flutter国际化插件interactive_i18n的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter国际化插件interactive_i18n的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是如何在Flutter项目中使用interactive_i18n插件来实现国际化的一个简单示例。interactive_i18n是一个强大的插件,可以帮助你轻松管理Flutter应用中的多语言支持。

第一步:添加依赖

首先,你需要在pubspec.yaml文件中添加interactive_i18n的依赖:

dependencies:
  flutter:
    sdk: flutter
  interactive_i18n: ^x.y.z  # 请替换为最新版本号

然后运行flutter pub get来安装依赖。

第二步:配置interactive_i18n

在你的项目中创建一个新的Dart文件(例如i18n_config.dart)来配置interactive_i18n

import 'package:interactive_i18n/interactive_i18n.dart';

class MyI18nConfig extends I18nConfig {
  @override
  String get defaultLocale => 'en'; // 默认语言

  @override
  List<Locale> get supportedLocales => [
    Locale('en', 'US'), // 英文
    Locale('zh', 'CN'), // 中文
    // 添加更多语言支持
  ];

  @override
  Map<String, Map<String, String>> get translations => {
    'en': {
      'hello': 'Hello',
      'welcome': 'Welcome',
    },
    'zh': {
      'hello': '你好',
      'welcome': '欢迎',
    },
    // 添加更多语言的翻译
  };
}

第三步:初始化interactive_i18n

在你的main.dart文件中,初始化interactive_i18n并设置全局的翻译服务:

import 'package:flutter/material.dart';
import 'package:interactive_i18n/interactive_i18n.dart';
import 'i18n_config.dart';

void main() {
  I18n.setup(MyI18nConfig());
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: I18n.of(context)!.translate('app.title'), // 你可以在这里使用翻译
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(I18n.of(context)!.translate('hello')),
      ),
      body: Center(
        child: Text(I18n.of(context)!.translate('welcome')),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          // 示例:切换语言
          I18n.of(context)?.changeLocale(Locale('zh', 'CN'));
        },
        tooltip: 'Change Language',
        child: Icon(Icons.translate),
      ),
    );
  }
}

第四步:运行应用

现在,你可以运行你的Flutter应用,并看到初始的默认语言(在这个例子中是英文)。点击浮动操作按钮(FAB)将语言切换到中文。

总结

通过上述步骤,你已经成功地在Flutter项目中使用interactive_i18n插件实现了国际化。你可以根据需要扩展翻译内容和支持的语言。希望这个示例对你有所帮助!

回到顶部