Flutter媒体中介插件flutter_mediator_simple的使用
Flutter媒体中介插件flutter_mediator_simple的使用
Flutter Media Mediator Simple是一个用于Flutter的状态管理包。简单、高效且易于使用。
目录
开始使用
运行以下命令:
$ flutter pub add flutter_mediator_simple
这将在你的pubspec.yaml
文件中添加如下依赖(并隐式地运行flutter pub get
):
dependencies:
flutter_mediator_simple: "^1.2.1"
或者,你的编辑器可能支持flutter pub get
。查阅你的编辑器文档以了解更多信息。
导入它
在你的Dart代码中,你可以使用以下导入语句:
import 'package:flutter_mediator_simple/flutter_mediator_simple.dart';
有关如何开始使用Flutter的更多帮助,请参阅在线文档。
用法
- 声明需要管理的变量,并添加
.rx
后缀,使其成为中介变量。 - 创建
Subscriber
小部件。任何在Subscriber
小部件内部使用的中介变量都会在更新时自动重建该小部件。
用例1:类型为Int
的中介变量
步骤1:声明中介变量_int1
在var.dart
文件中声明中介变量_int1
:
/// Mediator Variable: int1
final _int1 = 0.rx; // or `final _int1 = Rx(0);`
int get int1 => _int1.value;
set int1(value) => _int1.value = value;
// optional
get int1Subscribe => _int1.subscribe;
String get int1Notify => _int1.notify;
步骤2:创建使用_int1
的Subscriber
小部件
Subscriber(
() {
return Text(
'int1: $int1', // 使用中介变量`_int1`
style: Theme.of(subscriberContext).textTheme.headlineMedium,
);
},
),
更新int1
将自动重建相应的Subscriber
小部件。
@override
Widget build(BuildContext context) {
return DefaultTabController(
initialIndex: 0,
length: myTabs.length,
child: Scaffold(
floatingActionButton: FloatingActionButton(
onPressed: () {
switch (_tabController.index) {
case 0:
int1++;
break;
case 1:
int2++;
break;
case 2:
int3++;
break;
case 3:
updateListItem();
break;
case 4:
int1++;
break;
default:
}
},
child: const Icon(Icons.add),
),
),
);
}
用例2:类型为List
的中介变量
步骤1:声明中介变量_data
在var.dart
文件中声明中介变量_data
:
/// Mediator Variable: data
final _data = <ListItem>[].rx; //or `RxList(<ListItem>[]);`
List<ListItem> get data => _data.value;
set data(List<ListItem> value) => _data.value = value;
SubscriberFn get dataSubscribe => _data.subscribe;
List<ListItem> get dataNotify => _data.notify;
步骤2:创建使用_data
的Subscriber
小部件
return Scaffold(
appBar: AppBar(title: const Text('List Demo')),
body: Subscriber(
() => GridView.builder(
itemCount: data.length, // 使用中介变量`_data`
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: (MediaQuery.of(subscriberContext).orientation == Orientation.portrait) ? 5 : 10,
),
itemBuilder: (context, index) {
final item = data[index];
final widget = Padding(
padding: const EdgeInsets.all(7.0),
child: Card(
color: item.color,
child: Padding(
padding: const EdgeInsets.all(3.0),
child: GridTile(
footer: Text("${item.units}"),
child: Text(item.item),
),
),
).animate().fade(duration: 125.ms).scale(delay: 125.ms),
);
return widget;
},
),
),
);
步骤3:实现更新函数
void updateListItem() {
final units = Random().nextInt(maxUnits) + 1;
final itemIdx = Random().nextInt(itemNames.length);
final itemName = itemNames[itemIdx];
final color = itemColors[Random().nextInt(itemColors.length)];
if (data.length >= maxItems) data.clear();
// 更新集合类型的中介变量
// data.add(ListItem(itemName, units, color));
_data.notify.add(ListItem(itemName, units, color)); // 通知小部件重建
}
使用notify
来通知订阅小部件重建当中介变量的类型为类并且通过方法添加项目时。
用例3:中介变量的间接使用和持久化
间接使用意味着订阅小部件不使用中介变量的值,而是依赖于它。
步骤1:安装i18n包flutter_i18n
并按照说明进行设置。
步骤1-1:在main.dart
中设置locale delegates。
return MaterialApp(
// ...
localizationsDelegates: [
FlutterI18nDelegate(
translationLoader: FileTranslationLoader(
forcedLocale: Locale(locale),
// useCountryCode: true,
fallbackFile: 'en',
basePath: 'assets/flutter_i18n',
decodeStrategies: [JsonDecodeStrategy()],
),
missingTranslationHandler: (key, locale) {
// ignore: avoid_print
print('--- Missing Key: $key, languageCode: ${locale!.languageCode}');
},
),
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
],
);
步骤1-2:在pubspec.yaml
中添加资源并在指定文件夹中准备locale文件。
# pubspec.yaml
flutter:
assets:
- assets/flutter_i18n/
步骤2:安装持久化包shared_preferences
。
步骤3:在var.dart
中声明中介变量_locale
和SharedPreferences。
/// Locale page
late SharedPreferences prefs; // for persistence
// Mediator Variable: locale
late Rx<String> _locale;
String get locale => _locale.value;
// set locale(String value) => _locale.value = value; // comment out
get localeSubscribe => _locale.subscribe;
String get localeNotify => _locale.notify;
步骤4:实现初始化持久化的函数。
initPersistence() async {
WidgetsFlutterBinding.ensureInitialized(); // for shared_Preferences
prefs = await SharedPreferences.getInstance();
final loc = prefs.getString("locale") ?? 'en'; // 默认locale为'en'
_locale = loc.rx; // 将_locale设为类型为`Rx<String>`的中介变量
}
步骤5:实现设置locale的方法。
set locale(String value) {
_locale.value = value;
prefs.setString("locale", value);
}
步骤6:实现更改locale的方法。
/// 更改locale,通过`String`[countryCode]
Future<void> changeLocale(BuildContext context, String countryCode) async {
if (countryCode != locale) {
final loc = Locale(countryCode);
await FlutterI18n.refresh(context, loc);
locale = countryCode; // 重建关联的订阅小部件
}
}
步骤7:在main.dart
中初始化持久化。
void main() async {
await initPersistence();
runApp(const MyApp());
}
步骤8(可选):在var.dart
中为String
实现扩展,以帮助构建locale的订阅小部件。
extension StringI18n on String {
/// String extension for i18n.
String i18n(BuildContext context) {
return FlutterI18n.translate(context, this);
}
/// String extension for i18n
/// use `_locale.subscribe` to create Subscriber widget of locale.
Widget sub18n(BuildContext context, {TextStyle? style}) {
return _locale.subscribe(
() => Text(FlutterI18n.translate(context, this), style: style),
);
}
}
步骤9:在main.dart
中创建locale的订阅小部件。
Widget localeTxt(BuildContext context, String name) {
return SizedBox(
width: 250,
child: Row(
children: [
// * Step: Create a Subscriber widget
localeSubscribe(() => Text('${'app.hello'.i18n(context)} ')),
Text('$name, '),
// * Or use the string extension `sub18n`(in var.dart)
'app.thanks'.sub18n(context),
],
),
);
}
步骤10:在类_RadioGroupState
中处理radio状态以更改locale。
Future<void> _handleRadioValueChange1(Object? value) async {
await changeLocale(context, value!.toString());
setState(() {});
}
用例4:计算型中介变量
步骤1:在var.dart
中声明计算型中介变量_sum
。
/// Computed Mediator Variable: sum
final _sum = Rx(() => int1 + int2 + int3 as dynamic);
get sum => _sum.value;
set sum(value) => _sum.value = value;
步骤2:创建使用sum
的Subscriber
小部件。
Subscriber(
() {
return Text(
'sum(computed): $sum',
style: Theme.of(subscriberContext).textTheme.headlineLarge,
);
},
),
步骤2a(可选):根据需要更改计算函数。
floatingActionButton: FloatingActionButton(
onPressed: () {
if (sum is int && sum >= 10) {
sum = () => "excess upper bound($sum)";
}
// ...
}
),
或者,将更改合并到计算函数中。
final _sum = Rx(() {
final res = int1 + int2 + int3;
if (res <= 10) {
return res;
}
return "excess upper bound($res)";
});
订阅
要为中介变量的间接使用创建订阅小部件。
间接使用意味着订阅小部件不使用中介变量的值,而是依赖于它。
例如,locale用例。
通知
通知以重建与中介变量相关的方面。
当中介变量的类型为Class
且通过方法添加项目时使用。
信号
中介变量可以通过Signal
注解和类型别名初始化。
例如,
final _int1 = 0.signal;
final _int2 = Signal(0);
final _int3 = Signal(0);
// 计算型中介变量
final _sum = Signal(() => int1 + int2 + int3);
订阅者上下文
可以通过getter subscriberContext
获取订阅者的上下文。
例如:
Subscriber(
() {
return Text(
'int1: $int1',
style: Theme.of(subscriberContext).textTheme.headlineMedium,
);
},
),
VS Code代码片段
使用VS Code代码片段来帮助键入样板代码。
例如,snippet_Flutter_Mediator__statelessful.code-snippets
,
getset
- 获取/设置中介变量cgetset
- 获取/设置计算型中介变量sub1
- 创建箭头函数的订阅小部件subs
- 创建多行的订阅小部件
带动画的状态管理
通过使用flutter_animate
库,可以轻松地将动画添加到中介变量。如果每次中介变量变化都需要动画,则只需向animate
添加一个ValueKey
。
例如,在main.dart
中:
Subscriber(
() {
return Text(
'int1: $int1', // 使用中介变量`_int1`
style: Theme.of(subscriberContext).textTheme.headlineMedium,
)
.animate(key: ValueKey(int1))
.fade(duration: 125.ms)
.scale(delay: 125.ms);
},
);
更多关于Flutter媒体中介插件flutter_mediator_simple的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html