Flutter语言翻译插件fluent_translator的使用

Flutter语言翻译插件fluent_translator的使用

Introduction

什么是Fluent? 它是一个帮助你通过代码生成技术处理项目翻译的Flutter包。

为什么使用Fluent? Fluent旨在消除开发者在构建应用翻译时所写的冗余代码。它不是增加编码时间,而是浪费时间和容易出错的过程。那么为什么不让机器来做呢?

安装

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

dependencies:
  fluent_translator: [latest-version]

dev_dependencies:
  fluent_translator_generator: [latest-version]
  build_runner:

设置与使用

创建一个占位类并用@Fluent注解,该注解接受以下参数:

  • 一个Translatable对象列表(如果你手动提供翻译)
  • CSV文件路径(如果你的翻译将从CSV文件加载)
  • 支持的语言列表作为必需参数。
  • 一个备用语言作为必需参数。

注意:如果从CSV文件加载翻译,请确保首先在项目的pubspec.yaml文件的assets部分声明它。

/// 如果从CSV文件加载翻译

@Fluent(
  fromCSV: 'assets/csv_test.csv',
  fallbackLanguage: 'ar',
  supportedLanguages: ['ar', 'en', 'fr']
)
class Translations {}

/// 如果手动提供翻译到[Translatable]对象
@Fluent(
  fallbackLanguage: 'ar',
  supportedLanguages: [
    'ar',
    'en',
    'fr',
  ],
  translations: [
    Translatable(
      arabic: 'مرحبا',
      english: 'Hello',
      french: 'Salut',
      fieldName: 'helloText',
    )
  ],
)
class Translations {}

注意:如果同时提供CSV文件和Translatable对象列表,Fluent会覆盖Translatable对象的内容为CSV文件的内容。不会添加来自两个资源的内容。

注意:确保你在supportedLanguages列表中使用有效的ISO-639-1语言代码。你可以在这里找到完整的列表。

最后,你需要启动build_runner来开始翻译代码生成,使用命令flutter pub run build_runner build一次或使用命令flutter pub run build_runner watch持续跟踪文件系统的变化,并自动更新翻译。

CSV文件内容结构

为了正确解析CSV文件,请遵循以下规则结构化其内容:

  • 从单元格A1开始,在每一列的第一个单元格中添加所有语言(例如:ar, en, fr, …等)。
  • 在最后一个语言单元格后直接添加一个单元格,文本为"fieldName"。
  • 将特定语言的所有翻译列表添加到与其语言相关的列中(例如:阿拉伯语翻译在ar列中)。
  • fieldName列中列出每个翻译的唯一对应字段名。如果此列中的任何字段名重复会导致代码生成过程出错。
  • 如果需要在CSV文件中添加额外信息,请跳过fieldName列右边的一个空列。任何类型的数据都会被忽略并且不会以任何形式解析到代码中。
  • 确保没有空列添加在语言列之间或在fieldName列之前。
  • 确保fieldName拼写和格式(驼峰命名法)正确。

使用语言管理器

Fluent不仅生成不同语言的翻译,还生成一个Language Manager,在应用程序运行期间协调语言更改与可用翻译。

获取初始语言

LanguageManager类包含init()函数,默认情况下获取设备当前语言并设置为你的区域设置。如果需要语言管理器查询本地缓存系统(例如:共享偏好设置),可以传递名为LanguageSource.LOCAL_CACHE的参数,可以在任何时候将其更改为LanguageSource.DEVICE以重置默认设置。

检测运行时语言更改

LanguageManager会通过提供onLanguageChanged()来帮助你监听任何运行时语言更改,该函数传递一个字符串值作为更新后的区域代码。建议在应用程序的最早点实现它(例如:MyApp类)。如果你正在使用任何先前的语言流监听器,onLanguageChanged()可以和平地替代它,而不会造成明显的中断。值得注意的是,你可以在应用程序的任何地方使用LanguageManager.currentCode获取最近的语言。

更新远程服务器语言

LanguageManager配备了setServerLocale()函数,能够更新登录实体(例如:客户、用户等)在服务器数据库上的语言设置,以便从服务器获取的所有未来结果都应翻译为你更新后的语言区域。你需要向setServerLocale()提供一些参数来帮助它完成任务。languageNodeNamelocaleid是执行服务器请求所需的参数。同时,你可以告诉LanguageManager通过将locallyCached参数设置为true来缓存此语言,因为它默认不会缓存你的语言以节省资源并提高性能。

释放资源

所有的LanguageManager流和监听器都可以通过调用dispose()函数取消订阅并从内存中释放,这将由Dart垃圾收集器(DGC)轻松处理。与Init()不同,建议在应用程序的最新点调用dispose(),通常是在MyApp类小部件的dispose()函数中。

完整示例Demo

下面是一个完整的示例,展示了如何使用fluent_translator插件进行语言翻译。

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

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

class MyApp extends StatelessWidget {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  [@override](/user/override)
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  late LanguageManager _languageManager;

  [@override](/user/override)
  void initState() {
    super.initState();
    // 初始化语言管理器
    _languageManager = LanguageManager(
      fallbackLanguage: 'ar',
      supportedLanguages: ['ar', 'en', 'fr'],
    );

    // 监听语言变化
    _languageManager.onLanguageChanged.listen((locale) {
      print('Language changed to: $locale');
    });

    // 初始化语言
    _languageManager.init();
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Language Translation Demo'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(
              'Hello World',
              style: TextStyle(fontSize: 24),
            ),
            SizedBox(height: 20),
            ElevatedButton(
              onPressed: () {
                // 切换语言
                _languageManager.setLocale('en');
              },
              child: Text('Switch to English'),
            ),
            SizedBox(height: 20),
            ElevatedButton(
              onPressed: () {
                // 重新初始化语言
                _languageManager.init();
              },
              child: Text('Reinitialize Language'),
            ),
          ],
        ),
      ),
    );
  }

  [@override](/user/override)
  void dispose() {
    // 释放资源
    _languageManager.dispose();
    super.dispose();
  }
}

更多关于Flutter语言翻译插件fluent_translator的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter语言翻译插件fluent_translator的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,关于在Flutter中使用fluent_translator插件来实现语言翻译功能,下面是一个简单的代码示例,展示了如何集成和使用该插件。

首先,确保你已经在pubspec.yaml文件中添加了fluent_translator依赖:

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

然后运行flutter pub get来获取依赖。

接下来,在你的Flutter项目中,你可以按照以下步骤使用fluent_translator插件:

  1. 导入插件

在你的Dart文件中导入fluent_translator插件:

import 'package:fluent_translator/fluent_translator.dart';
  1. 初始化翻译器

在需要翻译文本的地方,你可以创建一个FluentTranslator实例,并使用它进行翻译。通常,你可能希望在一个全局或单例类中初始化这个实例,以便在整个应用中复用。

class TranslationService {
  static FluentTranslator? _translator;

  static Future<FluentTranslator> getTranslator() async {
    if (_translator == null) {
      // 你可以在这里配置翻译API的key或其他设置
      // 例如,如果fluent_translator支持配置,你可以在这里设置
      _translator = FluentTranslator();
      // 注意:实际的初始化可能涉及更多的配置,这里只是示例
    }
    return _translator!;
  }
}

注意FluentTranslator的初始化可能涉及实际的API密钥或其他敏感信息,这里仅作为示例,并未包含实际的初始化细节。你需要参考fluent_translator的官方文档来正确初始化。

  1. 进行翻译

一旦你有了FluentTranslator的实例,你可以使用它来翻译文本。

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  final translator = await TranslationService.getTranslator();

  runApp(MyApp(translator: translator));
}

class MyApp extends StatelessWidget {
  final FluentTranslator translator;

  MyApp({required this.translator});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Flutter Translation Demo'),
        ),
        body: Center(
          child: FutureBuilder<String>(
            future: translator.translate(
              'Hello, world!',
              from: 'en',
              to: 'es',  // 西班牙语
            ),
            builder: (context, snapshot) {
              if (snapshot.connectionState == ConnectionState.done) {
                if (snapshot.hasError) {
                  return Text('Error: ${snapshot.error}');
                } else {
                  return Text('Translated Text: ${snapshot.data}');
                }
              } else {
                return CircularProgressIndicator();
              }
            },
          ),
        ),
      ),
    );
  }
}

在这个示例中,我们创建了一个TranslationService类来管理FluentTranslator实例的创建。在MyApp中,我们使用FutureBuilder来异步获取翻译结果,并在UI中显示。

注意:上面的代码示例是基于假设FluentTranslator有一个translate方法,该方法接受源文本、源语言和目标语言作为参数,并返回一个Future<String>。然而,实际的fluent_translator插件的API可能有所不同,因此你需要参考其官方文档来调整代码。

由于fluent_translator插件的具体API和实现细节可能随时间变化,因此强烈建议查阅最新的官方文档和示例代码来获取准确的信息。

回到顶部