Flutter本地化配置管理插件flutter_floc的使用
Flutter本地化配置管理插件flutter_floc的使用
简介
Flutter Floc 帮助你快速创建表单,减少样板代码,并提供帮助程序以将视图与表单状态连接起来。
动机
创建表单一直是一项重复性任务。在 Dart 中,有一些包可以帮助你减少所需的样板代码,例如:
formz 是一个提供低级 API 来管理输入状态的包。
flutter_form_bloc 是一个提供高级 API 来管理表单的包,包括验证等。然而,flutter_form_bloc 缺乏一些功能,其中之一就是测试。
我们实际需要一个强大且可测试的表单管理器,并且我们喜欢 bloc。为此,我们基于 flutter_form_bloc 创建了自己的版本。
开始使用
对于如何开始使用 Flutter,可以查看 在线文档,该文档提供了教程、示例、移动开发指南和完整的 API 参考。
安装
在你的 Flutter 应用(pubspec.yaml)依赖列表中添加 flutter_floc
包:
dependencies:
flutter:
sdk: flutter
flutter_floc: ^0.0.0-dev.8
使用
创建一个表单 BLoC
- 创建一个名为
register_form_bloc.dart
的新文件(或你喜欢的任何名称)。 - 定义一个继承自
FormBloc
的类RegisterFormBloc
:
// FormBloc<String>,String 可以替换为你喜欢的任何表单响应类型
class RegisterFormBloc extends FormBloc<String> {
}
- 定义表单字段:
// username 是必需的
static final username = FormField<String>(
name: 'username',
initialValue: '',
validators: [
FieldValidator(Validator.required),
],
);
// password 是必需的,并且应该包含至少 6 个字符
static final password = FormField<String>(
name: 'password',
initialValue: '',
validators: [
FieldValidator(Validator.required),
FieldValidator(Validator.min6Chars),
],
);
// confirmPassword 是必需的,并且应与 "password" 字段具有相同的值
static final confirmPassword = FormField<String>(
name: 'confirmPassword',
initialValue: '',
validators: [
FieldValidator(Validator.required),
FieldValidator(
Validator.confirmPassword,
fieldSubscriptions: [password],
),
],
);
- 在表单构造函数中添加字段:
class RegisterFormBloc extends FormBloc<String> {
RegisterFormBloc() {
addFields([password, username, confirmPassword]);
}
}
- 你可以覆盖
onSubmit
方法,当表单提交并有效时会触发此方法:
@override
void onSubmit(fields) async {
// 你可以在其中进行 HTTP 调用
print(fields['username']);
print(fields['password']);
print(fields['confirmPassword']);
emitSuccess('success response : ok');
}
现在让我们为这些功能添加一些 UI。
- 在你的小部件树中的某个位置添加一个
FormBlocListener
(对于那些来自bloc
包的人来说,它基于BlocListener
)。FormBlocListener
提供了一些在表单生命周期期间触发的处理器(onSubmitting
、onSuccess
、onFailure
):
class ExampleForm extends StatelessWidget {
@override
Widget build(BuildContext context) {
return FormBlocListener<ExampleFormBloc, String>(
onSubmitting: (context, state) {
print('Loading...');
},
onSuccess: (context, state) {
print('Success !');
print(state.response);
},
onFailure: (context, state) {
print('Failure !');
print(state.response);
},
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
// 字段位于一个 `TextFieldBlocBuilder` 中,该构建器会在字段状态更改时更新
TextFieldBlocBuilder<ExampleFormBloc>(
fieldName: 'username',
decoration: InputDecoration(hintText: 'Username'),
),
TextFieldBlocBuilder<ExampleFormBloc>(
fieldName: 'password',
obscureText: true,
decoration: InputDecoration(hintText: 'Password'),
),
TextFieldBlocBuilder<ExampleFormBloc>(
fieldName: 'confirmPassword',
obscureText: true,
decoration: InputDecoration(hintText: 'Confirm password'),
),
// 按钮强制字段验证
MaterialButton(
onPressed: () {
context.read<ExampleFormBloc>().validate();
},
child: Text('Validate'),
),
// 按钮触发表单提交
MaterialButton(
onPressed: () {
context.read<ExampleFormBloc>().submit();
},
child: Text('Submit'),
)
],
),
);
}
}
至此,你已经完成了第一个 FormBLoC。
验证器
你可以创建简单的验证器,例如一个最小长度为 6 个字符的验证器,如下所示:
String min6Chars(String value, Map<String, dynamic> fields) {
if (value == null || value.isEmpty || value.runes.length < 6) {
return 'min 6 chars';
}
return null;
}
如果无错误,则返回值为 null。否则,它是一个字符串,返回值被视为 error key
,将在 UI 中传递。
要将此验证器添加到字段中,只需将其添加到字段验证器列表中:
static final 6minField = FormField<String>(
name: '6minField',
initialValue: '',
validators: [
FieldValidator(min6Chars),
],
);
依赖其他值的验证器(确认密码情况)
验证器可以依赖于其他字段的值:
String confirmPassword(String value, Map<String, dynamic> fields) {
if (value != fields['password']) {
return 'different';
}
return null;
}
第二个 fields
参数包含依赖字段。要向验证器添加依赖项,只需在 confirmPassword
验证器的 fieldSubscriptions
名称参数中定义它们:
static final confirmPassword = FormField<String>(
name: 'confirmPassword',
initialValue: '',
validators: [
FieldValidator(Validator.required),
FieldValidator(
Validator.confirmPassword,
// 我们可以在这里添加其他字段
fieldSubscriptions: [password],
),
],
);
更多关于Flutter本地化配置管理插件flutter_floc的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter本地化配置管理插件flutter_floc的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,下面是一个关于如何使用Flutter本地化配置管理插件flutter_floc
的示例。这个插件允许你轻松地在Flutter应用中实现本地化(i18n)和国际化(l10n)。
1. 添加依赖
首先,你需要在pubspec.yaml
文件中添加flutter_floc
依赖:
dependencies:
flutter:
sdk: flutter
flutter_floc: ^4.0.0 # 请检查最新版本号
然后运行flutter pub get
来安装依赖。
2. 配置Flutter应用
在你的Flutter应用的main.dart
文件中,你需要配置flutter_floc
。以下是一个基本的配置示例:
import 'package:flutter/material.dart';
import 'package:flutter_floc/flutter_floc.dart';
void main() {
// 初始化FlutterLocalizations
FlutterLocalizations.globalLocaleOverride = Locale('en'); // 默认为英语
// 初始化flutter_floc
runApp(
FlocProvider(
// 传递一个包含所有支持的语言环境的Map
locales: [
Locale('en', ''), // 英语
Locale('zh', ''), // 中文
],
delegate: AppLocalizationDelegate(),
child: MyApp(),
),
);
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
localizationsDelegates: context.localizationDelegates,
supportedLocales: context.supportedLocales,
locale: context.locale,
home: HomeScreen(),
);
}
}
class AppLocalizationDelegate extends FlocDelegate {
@override
Map<String, Map<String, String>> loadLocalizedStrings() {
return {
'en': {
'welcome': 'Welcome',
'goodbye': 'Goodbye',
},
'zh': {
'welcome': '欢迎',
'goodbye': '再见',
},
};
}
}
3. 使用本地化字符串
在你的UI组件中,你可以使用FlocProvider.of(context)
来获取本地化字符串。例如:
import 'package:flutter/material.dart';
import 'package:flutter_floc/flutter_floc.dart';
class HomeScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
final floc = FlocProvider.of(context);
return Scaffold(
appBar: AppBar(
title: Text(floc.translate('welcome')),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(floc.translate('welcome')),
ElevatedButton(
onPressed: () {
// 模拟切换语言
floc.setLocale(Locale('zh'));
},
child: Text('Switch to Chinese'),
),
Text(floc.translate('goodbye')),
],
),
),
);
}
}
4. 切换语言
在上面的示例中,我们通过一个按钮来模拟切换语言。在实际应用中,你可能会将这个功能集成到应用设置或者一个下拉菜单中。
5. 完整代码
将上述代码片段整合在一起,你将得到一个完整的Flutter应用,它支持英语和中文的本地化:
import 'package:flutter/material.dart';
import 'package:flutter_floc/flutter_floc.dart';
void main() {
FlutterLocalizations.globalLocaleOverride = Locale('en');
runApp(
FlocProvider(
locales: [
Locale('en', ''),
Locale('zh', ''),
],
delegate: AppLocalizationDelegate(),
child: MyApp(),
),
);
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
localizationsDelegates: context.localizationDelegates,
supportedLocales: context.supportedLocales,
locale: context.locale,
home: HomeScreen(),
);
}
}
class AppLocalizationDelegate extends FlocDelegate {
@override
Map<String, Map<String, String>> loadLocalizedStrings() {
return {
'en': {
'welcome': 'Welcome',
'goodbye': 'Goodbye',
},
'zh': {
'welcome': '欢迎',
'goodbye': '再见',
},
};
}
}
class HomeScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
final floc = FlocProvider.of(context);
return Scaffold(
appBar: AppBar(
title: Text(floc.translate('welcome')),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(floc.translate('welcome')),
ElevatedButton(
onPressed: () {
floc.setLocale(Locale('zh'));
},
child: Text('Switch to Chinese'),
),
Text(floc.translate('goodbye')),
],
),
),
);
}
}
这个示例展示了如何使用flutter_floc
插件在Flutter应用中实现本地化。你可以根据需要扩展这个示例,添加更多的语言和本地化字符串。