Flutter本地化CSV文件支持插件csv_localizations的使用

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

Flutter本地化CSV文件支持插件csv_localizations的使用

标题

csv_localizations

内容

一个用于Flutter的最小CSV本地化包。

安装

pubspec.yaml中添加csv_localizationsflutter_localizations

dependencies:
  flutter_localizations:
    sdk: flutter
  csv_localizations: <last-version>

将单个CSV文件资产添加到pubspec.yaml中。

flutter:
  assets:
    - assets/translations.csv

MaterialApp中添加CsvLocalizationsDelegate和支持的语言。

MaterialApp(
  localizationsDelegates: [
    // delegate from flutter_localization
    ...GlobalMaterialLocalizations.delegates,
    // delegate from csv_localizations
    CsvLocalizationsDelegate(path: 'assets/translations.csv'),
  ],
  supportedLocales: [
    Locale('en'),
    Locale('nb'),
  ],
)

iOS 注意事项

ios/Runner/Info.plist中添加支持的语言,如:

<key>CFBundleLocalizations</key>
<array>
	<string>en</string>
	<string>nb</string>
</array>

格式

CSV文件是一个简单的表格文本文件,列由逗号分隔,行由换行符分隔。每列代表特定语言的翻译,每行代表给定键的翻译。

示例表:

key en nb
Hi Hi Hei
Dog Dog Hund
Cat Cat Katt

提示1:多行字符串应包裹在引号中。

示例CSV:

key,en,nb
Hi,Hi,Hei
Dog,Dog,Hund
Cat,Cat,Katt
my_img,assets/en.png,assets/nb.png

提示2:键可以指向本地资源,如图像。

API

使用以下代码进行翻译:

CsvLocalizations.instance.string('Hi')

或添加一个String扩展:

extension LocalizedString on String {
  String tr(BuildContext context) => CsvLocalizations.instance.string(this);
}

注意:如果某个值不存在于给定的键,则返回该键本身。

我们还支持numintdouble通过以下方式:

CsvLocalizations.instance.numValue('my_num')

CsvLocalizations.instance.intValue('my_int')

CsvLocalizations.instance.doubleValue('my_double')

配置

支持csv包的所有配置。

可以通过CsvLocalizationsConfigurations设置它。

默认配置如下:

const CsvLocalizationsConfigurations({
  this.fieldDelimiter = ',',
  this.textDelimiter = '"',
  this.textEndDelimiter = '"',
  this.eol = '\n',
  this.convertEmptyTo = '',
  this.allowInvalid = true,
  this.shouldParseNumbers = true,
});

示例

查看example

import 'package:csv_localizations/csv_localizations.dart';
import 'package:flutter/material.dart';
import 'package:flutter_localizations/flutter_localizations.dart';

import 'string_ext.dart';

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

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      localizationsDelegates: const [
        ...GlobalMaterialLocalizations.delegates,
        CsvLocalizationsDelegate(
          path: 'assets/translations.csv',
          configurations: CsvLocalizationsConfigurations(
            eol: '\n',
            fieldDelimiter: ',',
            shouldParseNumbers: true,
          ),
        ),
      ],
      supportedLocales: const [
        Locale('en', 'GB'),
        Locale('en', 'US'),
        Locale('en'),
        Locale('nb'),
      ],
      theme: ThemeData(
        primarySwatch: Colors.blue,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: const MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({Key? key}) : super(key: key);

  [@override](/user/override)
  MyHomePageState createState() => MyHomePageState();
}

class MyHomePageState extends State<MyHomePage> {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('csv_localizations'),
      ),
      body: Column(
        mainAxisAlignment: MainAxisAlignment.start,
        crossAxisAlignment: CrossAxisAlignment.start,
        children: <Widget>[
          Text(
            'Hi'.tr,
            style: const TextStyle(
              fontSize: 24,
            ),
          ),
          Image.asset(
            'my_img'.tr,
            width: 64,
            height: 64,
            fit: BoxFit.contain,
            filterQuality: FilterQuality.none,
          ),
          Text(
            'Multiline'.tr,
            style: const TextStyle(
              fontSize: 24,
            ),
          ),
          Text(
            'num'.numValue.toString(),
            style: const TextStyle(
              fontSize: 24,
            ),
          ),
          Text(
            'int'.intValue.toString(),
            style: const TextStyle(
              fontSize: 24,
            ),
          ),
          Text(
            'double'.doubleValue.toString(),
            style: const TextStyle(
              fontSize: 24,
            ),
          ),
          Text(
            'someStringWeHaventTranslatedYet'.tr,
            style: const TextStyle(
              fontSize: 24,
            ),
          ),
        ],
      ),
    );
  }
}

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

1 回复

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


当然,下面是一个关于如何在Flutter项目中使用csv_localizations插件(尽管实际上并不存在一个名为csv_localizations的官方插件,通常本地化相关的插件名为flutter_localizations,而CSV文件处理相关的插件则可能是csv等。这里我将结合CSV文件处理和本地化的概念,展示如何在Flutter项目中读取CSV文件并处理本地化数据)。

为了处理CSV文件并实现本地化支持,我们通常会使用csv插件来读取CSV文件,并结合flutter_localizations插件来实现本地化功能。以下是一个简化的示例,展示如何读取CSV文件中的本地化字符串,并在Flutter应用中使用它们。

步骤 1: 添加依赖

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

dependencies:
  flutter:
    sdk: flutter
  csv: ^5.0.1  # 用于读取CSV文件的插件
  flutter_localizations:
    sdk: flutter  # Flutter自带的本地化支持插件

步骤 2: 准备CSV文件

创建一个CSV文件(例如translations.csv),其中包含本地化字符串。文件内容可能如下所示:

key,en,es,fr
greeting,Hello,Hola,Bonjour
farewell,Goodbye,Adiós,Au revoir

步骤 3: 读取CSV文件

在你的Flutter项目中创建一个服务或帮助类来读取CSV文件并解析本地化字符串。例如,创建一个LocalizationService类:

import 'dart:convert';
import 'package:csv/csv.dart';
import 'package:flutter/services.dart' show rootBundle;

class LocalizationService {
  static Map<String, Map<String, String>> _localizedStrings = {};

  Future<Map<String, String>> loadLocale(String locale) async {
    String csvContent = await rootBundle.loadString('assets/translations.csv');
    List<List<dynamic>> csvTable = List.from(csv.parse(csvContent));

    Map<String, String> localeStrings = {};
    for (int i = 1; i < csvTable.length; i++) {
      String key = csvTable[i][0];
      String value = csvTable[i][locale == 'en' ? 1 : (locale == 'es' ? 2 : 3)];
      localeStrings[key] = value;
    }

    _localizedStrings[locale] = localeStrings;
    return localeStrings;
  }

  String translate(String key, String locale) {
    return _localizedStrings[locale]?.containsKey(key) ?? false
        ? _localizedStrings[locale]![key]
        : key; // Return key if translation not found
  }
}

步骤 4: 使用本地化字符串

在你的Flutter应用中使用LocalizationService来获取并显示本地化字符串。例如,在MyApp小部件中:

import 'package:flutter/material.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'localization_service.dart';  // 导入你创建的LocalizationService

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      localizationsDelegates: [
        // 添加Flutter本地化的委托
        GlobalMaterialLocalizations.delegate,
        GlobalWidgetsLocalizations.delegate,
      ],
      supportedLocales: [
        Locale('en', ''),
        Locale('es', ''),
        Locale('fr', ''),
      ],
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: FutureBuilder<Map<String, String>>(
        future: LocalizationService().loadLocale(Locale.of(context).languageCode),
        builder: (context, snapshot) {
          if (snapshot.connectionState == ConnectionState.done) {
            Map<String, String> translations = snapshot.data ?? {};
            return Scaffold(
              appBar: AppBar(
                title: Text(translations['greeting'] ?? 'Hello'),
              ),
              body: Center(
                child: Text(translations['farewell'] ?? 'Goodbye'),
              ),
            );
          } else {
            return Center(child: CircularProgressIndicator());
          }
        },
      ),
    );
  }
}

注意

  1. 确保将translations.csv文件放在assets文件夹中,并在pubspec.yaml中声明它作为资产:
flutter:
  assets:
    - assets/translations.csv
  1. 上述代码是一个简化的示例,实际项目中可能需要更复杂的错误处理和状态管理。

通过上述步骤,你可以在Flutter应用中读取CSV文件中的本地化字符串,并根据当前语言环境显示相应的翻译。

回到顶部