Flutter国际化插件localization的使用

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

Flutter国际化插件localization的使用

Localization插件用于简化应用内的翻译工作。本文将详细介绍如何在Flutter项目中使用该插件进行国际化。

安装

首先,在pubspec.yaml文件中添加依赖:

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

flutter:
  assets:
    - lib/i18n/

请确保替换<last-version>为最新版本号。

接下来,在MaterialAppCupertinoApp中添加委托,并定义翻译JSON文件的路径:

@override
Widget build(BuildContext context) {
  // 设置json文件目录,默认值是['lib/i18n']
  LocalJsonLocalization.delegate.directories = ['lib/i18n'];

  // 或者设置一个翻译映射
  MapLocalization.delegate.translations = {
    Locale('en', 'US'): {
      'welcome-text': 'This text is in english',
    },
    Locale('es', 'ES'): {
      'welcome-text': 'Este texto esta en español',
    },
    Locale('pt', 'BR'): {
      'welcome-text': 'Este texto está em português',
    },
  };

  return MaterialApp(
    localizationsDelegates: [
      GlobalMaterialLocalizations.delegate,
      GlobalWidgetsLocalizations.delegate,
      GlobalCupertinoLocalizations.delegate,
      LocalJsonLocalization.delegate, // 使用json文件
      MapLocalization.delegate, // 或者使用映射
    ],
    supportedLocales: [
      Locale('en', 'US'),
      Locale('es', 'ES'),
      Locale('pt', 'BR'),
    ],
    home: HomePage(),
  );
}

JSON文件

创建翻译JSON文件,文件名应遵循语言和国家代码命名规则(如en_US.json, es_ES.json, pt_BR.json),并将它们放在配置的目录下(例如lib/i18n/):

  • lib/i18n/en_US.json
  • lib/i18n/es_ES.json
  • lib/i18n/pt_BR.json

示例翻译JSON文件内容如下:

en_US.json

{
  "welcome-text": "This text is in english"
}

es_ES.json

{
  "welcome-text": "Este texto esta en español"
}

pt_BR.json

{
  "welcome-text": "Este texto está em português"
}

使用

为了方便使用,扩展了String类,添加了i18n()方法。只需提供翻译JSON文件中的键作为字符串,并调用i18n()方法即可获取翻译文本:

String text = 'welcome-text'.i18n();
print(text); // 输出:'This text is in english'

还可以通过传递参数来实现动态文本:

{
  "welcome-text": "Welcome, %s"
}
String text = 'welcome-text'.i18n(['Peter']);
print(text); // 输出:'Welcome, Peter'

支持条件表达式来进行单复数处理:

{
  "person-text": "Welcome, %b{people:person}"
}
final count = 2;
String text = 'person-text'.i18n(
        [], // 如果没有%s占位符,args参数需要传空列表
        conditions: [count > 1]);
print(text); // 输出:'Welcome, people'

完整示例Demo

以下是一个完整的示例,展示了如何集成和使用Localization插件:

main.dart

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

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    LocalJsonLocalization.delegate.directories = ['lib/i18n'];

    return MaterialApp(
      title: 'Localization Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      localizationsDelegates: [
        GlobalMaterialLocalizations.delegate,
        GlobalWidgetsLocalizations.delegate,
        GlobalCupertinoLocalizations.delegate,
        LocalJsonLocalization.delegate,
      ],
      supportedLocales: [
        Locale('en', 'US'),
        Locale('es', 'ES'),
        Locale('pt', 'BR'),
      ],
      localeResolutionCallback: (locale, supportedLocales) {
        if (supportedLocales.contains(locale)) {
          return locale;
        }

        if (locale?.languageCode == 'pt') {
          return Locale('pt', 'BR');
        }

        return Locale('en', 'US');
      },
      home: HomePage(),
    );
  }
}

home_page.dart

import 'package:flutter/material.dart';

class HomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    String welcomeText = 'welcome-text'.i18n();
    String personText = 'person-text'.i18n([], conditions: [2 > 1]);

    return Scaffold(
      appBar: AppBar(
        title: Text('Localization Demo'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(welcomeText),
            SizedBox(height: 20),
            Text(personText),
          ],
        ),
      ),
    );
  }
}

以上就是如何在Flutter项目中使用Localization插件进行国际化的完整指南。希望对您有所帮助!


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

1 回复

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


在Flutter应用中实现国际化(i18n)是一个常见的需求,flutter_localizations 包和 intl 包为我们提供了强大的支持。下面是一个使用 flutter_localizationsintl 包实现国际化的代码案例。

1. 添加依赖

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

dependencies:
  flutter:
    sdk: flutter
  flutter_localizations:
    sdk: flutter
  intl: ^0.17.0 # 确保使用最新版本

2. 创建语言文件

在你的项目根目录下创建一个 lib/l10n 文件夹,并在其中创建多个语言文件,例如 messages_en.dartmessages_zh.dart

messages_en.dart

import 'package:intl/intl.dart';

final Map<String, Map<String, String>> enTranslations = {
  'app_title': {
    'title': 'My Flutter App',
  },
  'greeting': {
    'hello': 'Hello!',
  },
};

class MessagesEn extends IntlLocale {
  const MessagesEn() : super('en');

  static MessagesEn of(BuildContext context) {
    return Localizations.of<MessagesEn>(context, MessagesEn)!;
  }

  String get appTitle => Intl.message(
    'My Flutter App',
    name: 'app_title_title',
    desc: 'Title of the application',
    locale: localeName,
  );

  String get hello => Intl.message(
    'Hello!',
    name: 'greeting_hello',
    desc: 'A greeting message',
    locale: localeName,
  );
}

messages_zh.dart

import 'package:intl/intl.dart';

final Map<String, Map<String, String>> zhTranslations = {
  'app_title': {
    'title': '我的Flutter应用',
  },
  'greeting': {
    'hello': '你好!',
  },
};

class MessagesZh extends IntlLocale {
  const MessagesZh() : super('zh');

  static MessagesZh of(BuildContext context) {
    return Localizations.of<MessagesZh>(context, MessagesZh)!;
  }

  String get appTitle => Intl.message(
    '我的Flutter应用',
    name: 'app_title_title',
    desc: '应用程序的标题',
    locale: localeName,
  );

  String get hello => Intl.message(
    '你好!',
    name: 'greeting_hello',
    desc: '一个问候语',
    locale: localeName,
  );
}

3. 创建 localizations_delegates.dart

lib/l10n 文件夹中创建一个 localizations_delegates.dart 文件,用于定义本地化委托。

import 'package:flutter/material.dart';
import 'messages_en.dart';
import 'messages_zh.dart';

class MyLocalizationsDelegate extends LocalizationsDelegate<Locale> {
  const MyLocalizationsDelegate();

  @override
  bool isSupported(Locale locale) {
    return locale.languageCode == 'en' || locale.languageCode == 'zh';
  }

  @override
  Future<Locale> load(Locale locale) async {
    return locale;
  }

  @override
  bool shouldReload(MyLocalizationsDelegate oldDelegate) {
    return false;
  }
}

class MyLocalizations {
  MyLocalizations(this.locale);

  final Locale locale;

  static MyLocalizations of(BuildContext context) {
    return Localizations.of<MyLocalizations>(context, MyLocalizations)!;
  }

  MessagesEn get en => MessagesEn.of(context);
  MessagesZh get zh => MessagesZh.of(context);

  String get appTitle {
    if (locale.languageCode == 'zh') {
      return zh.appTitle;
    } else {
      return en.appTitle;
    }
  }

  String get hello {
    if (locale.languageCode == 'zh') {
      return zh.hello;
    } else {
      return en.hello;
    }
  }
}

4. 在应用中使用本地化

MaterialApp 中设置 localizationsDelegatessupportedLocales

import 'package:flutter/material.dart';
import 'lib/l10n/localizations_delegates.dart';
import 'lib/l10n/messages_en.dart';
import 'lib/l10n/messages_zh.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      localizationsDelegates: [
        MyLocalizationsDelegate(),
        GlobalMaterialLocalizations.delegate,
        GlobalWidgetsLocalizations.delegate,
        GlobalCupertinoLocalizations.delegate,
      ],
      supportedLocales: [
        Locale('en', ''),
        Locale('zh', ''),
      ],
      locale: Locale('en'), // 默认语言
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final MyLocalizations localizations = MyLocalizations.of(context);

    return Scaffold(
      appBar: AppBar(
        title: Text(localizations.appTitle),
      ),
      body: Center(
        child: Text(localizations.hello),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          // 切换语言示例(这里仅为演示,实际使用中可能需要持久化用户选择的语言)
          Navigator.push(
            context,
            MaterialPageRoute<void>(
              builder: (BuildContext context) {
                return LanguageSelectorPage(currentLocale: Localizations.localeOf(context));
              },
            ),
          );
        },
        tooltip: 'Change Language',
        child: Icon(Icons.language),
      ),
    );
  }
}

class LanguageSelectorPage extends StatefulWidget {
  final Locale currentLocale;

  const LanguageSelectorPage({Key? key, required this.currentLocale}) : super(key: key);

  @override
  _LanguageSelectorPageState createState() => _LanguageSelectorPageState();
}

class _LanguageSelectorPageState extends State<LanguageSelectorPage> {
  Locale? _selectedLocale;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Select Language'),
      ),
      body: ListView(
        children: [
          ListTile(
            title: Text('English'),
            leading: Icon(Icons.language),
            onTap: () {
              setState(() {
                _selectedLocale = Locale('en');
                Navigator.popAndPushNamed(context, '/');
              });
            },
          ),
          ListTile(
            title: Text('中文'),
            leading: Icon(Icons.language),
            onTap: () {
              setState(() {
                _selectedLocale = Locale('zh');
                Navigator.popAndPushNamed(context, '/');
              });
            },
          ),
        ],
      ),
    );
  }
}

5. 运行应用

运行你的Flutter应用,你应该能看到默认显示英文标题和问候语。点击浮动按钮(FAB)可以切换到语言选择页面,选择中文后应用会重启并显示中文标题和问候语。

这个示例展示了如何使用 flutter_localizationsintl 包来实现Flutter应用的国际化。你可以根据需要扩展语言文件和本地化逻辑。

回到顶部