Flutter本地化管理插件easiest_remote_localization的使用

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

Flutter本地化管理插件easiest_remote_localization的使用

插件介绍

easiest_remote_localization 是一个与 Flutter 本地化插件 easiest_localization 配合使用的扩展包。它允许从任何远程源检索和集成 JSON 或 YAML 格式的本地化文件,从而实现动态更新和添加语言的功能,而无需更新应用程序。

安装

dependencies:
  easiest_remote_localization: ^1.0.3

设置

初始化过程只需四步,并且非常简单:

import 'package:easiest_localization/easiest_localization.dart';
import 'package:easiest_remote_localization/easiest_remote_localization.dart'; // <- 1️⃣ Import package
import 'package:flutter/material.dart';
import 'package:localization/localization.dart';

Future<void> main() async {
  runApp(const MyApp());
}

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

  @override
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  /// 2️⃣ 创建远程提供者 - 你可以创建多个,但通常只需要一个
  late final List<LocalizationProvider&lt;LocalizationMessages&gt;&gt; remoteProviders = [
    RemoteLocalizationProvider&lt;LocalizationMessages&gt;(
      /// 设置缓存时长
      /// 在此期间,用户将使用之前下载的内容
      cacheTTL: const Duration(hours: 3),

      /// 如果需要 - 您可以详细配置网络请求执行方式
      options: BaseOptions(),
      sources: [
        /// 描述每个支持的语言的“来源”
        ///
        /// 提示 - 由于“source”是一个非常简单的数据类,因此实现获取所有支持语言的来源完全远程是相当容易的。
        /// 这样,您不仅可以更改已支持语言的内容,还可以动态添加新语言。
        RemoteSource(
          locale: Locale('en'),
          url: 'https://indieloper.b-cdn.net/easiest_localization/en.json',
          type: SourceType.json,
        ),
        RemoteSource(
          locale: Locale('en', 'CA'),
          url: 'https://indieloper.b-cdn.net/easiest_localization/en_CA.json',
          type: SourceType.json,
        ),
        RemoteSource(
          locale: Locale('es'),
          url: 'https://indieloper.b-cdn.net/easiest_localization/es.json',
          type: SourceType.json,
        ),
        RemoteSource(
          locale: Locale('ru'),
          url: 'https://indieloper.b-cdn.net/easiest_localization/ru.json',
          type: SourceType.json,
        ),
      ],

      /// 指定工厂 `.fromJson` 以生成内容
      /// 如果没有更改设置,则该行将完全相同
      /// 如果更改了 `class_name` 参数,则将是 `<class_name>.fromJson`
      factory: (RemoteSource source, Json content) =&gt; LocalizationMessages.fromJson(content),
    ),
  ];

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      onGenerateTitle: (BuildContext context) =&gt; el.appTitle,

      /// 3️⃣ 使用 localizationsDelegatesWithProviders(remoteProviders) 而不是 localizationsDelegates
      localizationsDelegates: localizationsDelegatesWithProviders(remoteProviders),

      /// 4️⃣ 最后 - 使用 supportedLocalesWithProviders(remoteProviders) 而不是 supportedLocales
      supportedLocales: supportedLocalesWithProviders(remoteProviders),
      home: Home(),
    );
  }
}

缓存

您可以设置缓存时长(或禁用缓存),确保用户在一定时间内只下载一次本地化数据。这使得即使用户离线也能使用远程内容。缓存使用 shared_preferences 实现。

安全性

由于您的应用始终会有一个本地版本的本地化内容,即使远程内容无法加载(例如后端问题或用户无互联网且缓存为空),用户仍然可以看到本地版本的本地化内容。

如果添加了一个仅在远程可用的新语言并且从未下载过,系统会显示默认语言或列表中的第一个语言作为 fallback。

动态语言扩展

由于您可以存储任何语言的远程内容,包括尚未在应用中添加的新语言,这为实时添加新语言提供了可能,而无需更新应用。

最佳实践

为了最大化协同效应,请同时开发应用并添加或修改本地化内容。如果相应的设置设置为 save_merged_files_as: yamlsave_merged_files_as: json,则会在生成的本地化包中创建一个额外的 merged 文件夹,其中包含 JSON 或 YAML 文件,这些文件可以放置在 CDN 上。这个过程可以通过 CI/CD 完全自动化,使用户能够实时接收最新的内容更新。

然而,代码生成有一些限制:如果您删除或更改本地化文件中的任何键,这也将影响生成的代码以及 merged 文件夹中的文件。结果,旧版本的用户可能会收到来自远程源的内容,这些内容可能不包含所需的字段(因为它们被删除了或键名发生了变化)。这会导致尝试从修改后的远程源内容创建本地化类时出现错误,最终用户将看到本地内容。因此,在进行可能破坏向后兼容性的更改时,建议使用版本控制。

对于这一特定目的,配置中有 remote_version 参数,默认值为 null,这意味着生成的(综合)JSON/YAML 文件将位于路径 .../generated_localization_package/merged/。但是,如果指定版本,例如 2.0.0,文件将位于以下路径:.../generated_localization_package/merged/2.0.0/,因此每个版本的本地化都将有自己的文件集,并且所有这些文件都对用户可用。

示例应用

一个全面的例子应用可以在以下链接找到:

https://github.com/alphamikle/localization_battle


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

1 回复

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


当然,以下是如何在Flutter项目中使用easiest_remote_localization插件进行本地化管理的示例代码。这个插件允许你从远程服务器加载本地化资源,从而使应用能够动态更新本地化内容。

1. 添加依赖

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

dependencies:
  flutter:
    sdk: flutter
  easiest_remote_localization: ^最新版本号 # 请替换为最新的版本号

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

2. 配置插件

在你的Flutter项目的lib目录下,创建一个新的文件,比如localization_service.dart,用于配置和初始化本地化服务。

import 'package:flutter/material.dart';
import 'package:easiest_remote_localization/easiest_remote_localization.dart';

class LocalizationService {
  static EasyLocalizationController? _controller;

  static Future<EasyLocalizationController> init(BuildContext context) async {
    // 远程JSON文件的URL
    const String remoteLocalizationUrl = 'https://your-server.com/localization.json';

    // 初始化控制器
    _controller = EasyLocalizationController(
      supportedLocales: [Locale('en', ''), Locale('zh', '')], // 支持的语言列表
      path: remoteLocalizationUrl, // 远程JSON文件的路径
      fallbackLocale: Locale('en', ''), // 回退语言
      useOnlyLangCode: false, // 是否只使用语言代码
      loader: Center(child: CircularProgressIndicator()), // 加载指示器
    );

    // 等待控制器加载完成
    await _controller!.load();

    // 设置全局本地化委托
    EasyLocalization.of(context).controller = _controller!;

    return _controller!;
  }

  static EasyLocalizationController? get controller => _controller;
}

3. 初始化应用

在你的main.dart文件中,初始化LocalizationService并设置MaterialApplocalizationsDelegatessupportedLocales

import 'package:flutter/material.dart';
import 'package:easiest_remote_localization/easiest_remote_localization.dart';
import 'localization_service.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();

  // 创建并运行应用
  runApp(MyApp());
}

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  @override
  void initState() {
    super.initState();
    // 初始化本地化服务
    LocalizationService.init(context).then((_) {
      // 可以在这里执行其他初始化操作,比如导航到首页
    });
  }

  @override
  Widget build(BuildContext context) {
    return EasyLocalizationProvider(
      data: LocalizationService.controller, // 传递控制器
      child: MaterialApp(
        title: 'Flutter Demo',
        theme: ThemeData(
          primarySwatch: Colors.blue,
        ),
        localizationsDelegates: [
          // 添加EasyLocalization委托
          EasyLocalization.delegate,
          GlobalMaterialLocalizations.delegate,
          GlobalWidgetsLocalizations.delegate,
          GlobalCupertinoLocalizations.delegate,
        ],
        supportedLocales: LocalizationService.controller!.supportedLocales,
        home: MyHomePage(),
      ),
    );
  }
}

class MyHomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // 使用tr函数进行本地化文本显示
    return Scaffold(
      appBar: AppBar(
        title: Text(tr('app_name')), // 假设app_name是你在JSON文件中定义的一个键
      ),
      body: Center(
        child: Text(tr('welcome_message')), // 假设welcome_message是你在JSON文件中定义的一个键
      ),
    );
  }
}

4. 创建远程JSON文件

在你的服务器上创建一个名为localization.json的文件,内容如下:

{
  "en": {
    "app_name": "My App",
    "welcome_message": "Welcome to My App!"
  },
  "zh": {
    "app_name": "我的应用",
    "welcome_message": "欢迎来到我的应用!"
  }
}

5. 运行应用

现在你可以运行你的Flutter应用,它应该会从远程服务器加载本地化资源,并根据设备的语言设置显示相应的文本。

请确保你的远程服务器允许跨域请求(CORS),否则Flutter应用将无法加载JSON文件。

这个示例展示了如何使用easiest_remote_localization插件进行基本的本地化配置和管理。根据你的具体需求,你可能需要进一步自定义和扩展这个基础实现。

回到顶部