Flutter事件监听插件katana_listenables的使用
Flutter事件监听插件katana_listenables的使用
简介
在创建Flutter小部件时,您可能需要管理多个TextEditingController
、ValueNotifier
以及其他继承自ChangeNotifier
的控制器。通常情况下,您需要在State
中定义多个ChangeNotifier
继承类,或者创建一个继承自ChangeNotifier
的类用于状态管理,并为所有监听器添加addListener
。
为了简化上述实现,katana_listenables
插件提供了一种更简单的方式来创建继承自ChangeNotifier
的类,并通过传递继承自ChangeNotifier
的对象来监控其参数。当被监控的ChangeNotifier
发生更改时,更改会传播到其自身对象。
例如,以下代码展示了如何使用katana_listenables
:
[@listenables](/user/listenables)
class ControllerGroup with _$ControllerGroup, ChangeNotifier {
factory ControllerGroup({
required TextEditingController emailTextEditingController,
required TextEditingController passwordTextEditingController,
required FocusNode focusNode,
ValueNotifier<bool> checkTerms,
}) = _ControllerGroup;
}
当您运行build_runner
时,会自动生成一个继承自ChangeNotifier
(Listenable)的类。如果您将此加载到riverpod
中,例如:
final controllerProvider = ChangeNotifierProvider((_) {
return ControllerGroup(
emailTextEditingController: TextEditingController(),
passwordTextEditingController: TextEditingController(),
focusNode: FocusNode(),
checkTerms: ValueNotifier(false),
);
});
class TestPage extends ConsumerWidget {
[@override](/user/override)
Widget build(BuildContext context, WidgetRef ref) {
final controller = ref.watch(controllerProvider);
// 当controller中的emailTextEditingController内容更新时,controller也会收到更改通知并更新小部件
controller.emailTextEditingController.text = "New Text";
return Scaffold(
appBar: AppBar(title: Text("Test Page")),
body: Center(
child: TextField(
controller: controller.emailTextEditingController,
),
),
);
}
}
安装
要使用katana_listenables
,您需要导入以下包以进行代码生成:
flutter pub add katana_listenables
flutter pub add --dev build_runner
flutter pub add --dev katana_listenables_builder
实现
创建类
创建一个类如下所示:
- 添加
part '(filename).listenable.dart';
。 - 使用
[@listenables](/user/listenables)
注解定义的类,并混入_$(定义的类名)
和ChangeNotifier
。 - 在
factory
中创建构造函数,并定义您想要使用的继承自ChangeNotifier
和Listenable
的类作为参数。 - 在构造函数后写上
= _ (定义的类名)
。
示例代码:
// controller.dart
import 'package:flutter/material.dart';
import 'package:katana_listenables/katana_listenables.dart';
part 'controller.listenable.dart';
[@listenables](/user/listenables)
class ControllerGroup with _$ControllerGroup, ChangeNotifier {
factory ControllerGroup({
required TextEditingController emailTextEditingController,
required TextEditingController passwordTextEditingController,
required FocusNode focusNode,
ValueNotifier<bool> checkTerms,
}) = _ControllerGroup;
}
代码生成
通过输入以下命令进行自动代码生成:
flutter pub run build_runner build --delete-conflicting-outputs
使用方法
由于创建的类继承自ChangeNotifier
,因此可以像普通ChangeNotifier
一样使用它。
在State中使用
class TestPage extends StatefulWidget {
[@override](/user/override)
State<StatefulWidget> createState() => TestPageState();
}
class TestPageState extends State<TestPage> {
final controller = ControllerGroup(
emailTextEditingController: TextEditingController(),
passwordTextEditingController: TextEditingController(),
focusNode: FocusNode(),
checkTerms: ValueNotifier(false),
);
[@override](/user/override)
void initState() {
super.initState();
controller.addListener(_handledOnUpdate);
}
void _handledOnUpdate() {
setState(() {});
}
[@override](/user/override)
void dispose() {
super.dispose();
controller.removeListener(_handledOnUpdate);
controller.dispose();
}
[@override](/user/override)
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("Test Page")),
body: Center(
child: TextField(
controller: controller.emailTextEditingController,
),
),
);
}
}
在Riverpod中使用
final controllerProvider = ChangeNotifierProvider((_) {
return ControllerGroup(
emailTextEditingController: TextEditingController(),
passwordTextEditingController: TextEditingController(),
focusNode: FocusNode(),
checkTerms: ValueNotifier(false),
);
});
class TestPage extends ConsumerWidget {
[@override](/user/override)
Widget build(BuildContext context, WidgetRef ref) {
final controller = ref.watch(controllerProvider);
// 当controller中的emailTextEditingController内容更新时,controller也会收到更改通知并更新小部件
controller.emailTextEditingController.text = "New Text";
return Scaffold(
appBar: AppBar(title: Text("Test Page")),
body: Center(
child: TextField(
controller: controller.emailTextEditingController,
),
),
);
}
}
额外用法
添加方法
要添加方法,使用以下写作风格:
// controller.dart
import 'package:flutter/material.dart';
import 'package:katana_listenables/katana_listenables.dart';
part 'controller.listenable.dart';
[@listenables](/user/listenables)
class ControllerGroup with _$ControllerGroup, ChangeNotifier {
factory ControllerGroup({
required TextEditingController emailTextEditingController,
required TextEditingController passwordTextEditingController,
required FocusNode focusNode,
ValueNotifier<bool> checkTerms,
}) = _ControllerGroup;
ControllerGroup._(); // 额外要求
bool get checked => checkTerms?.value ?? false;
void someMethod() {
// 方法实现
}
}
完整示例Demo
以下是一个完整的示例,展示了如何使用katana_listenables
插件:
// Dart imports:
import 'dart:math';
// Flutter imports:
import 'package:flutter/material.dart';
// Package imports:
import 'package:katana_listenables/katana_listenables.dart';
part 'main.listenable.dart';
[@listenables](/user/listenables)
class ListenableValue with _$ListenableValue, ChangeNotifier {
factory ListenableValue({
required TextEditingController controller,
ValueNotifier<String> value,
}) = _ListenableValue;
ListenableValue._();
void get() {}
}
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
[@override](/user/override)
Widget build(BuildContext context) {
return MaterialApp(
home: const ListenablePage(),
title: "Flutter Demo",
theme: ThemeData(
primarySwatch: Colors.blue,
),
);
}
}
class ListenablePage extends StatefulWidget {
const ListenablePage({super.key});
[@override](/user/override)
State<StatefulWidget> createState() => ListenablePageState();
}
class ListenablePageState extends State<ListenablePage> {
final listenable = ListenableValue(
controller: TextEditingController(text: "before click"),
value: ValueNotifier("0"),
);
[@override](/user/override)
void initState() {
super.initState();
listenable.addListener(() {
setState(() {});
});
}
[@override](/user/override)
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text("Flutter Demo")),
body: ListView(
children: [
ListTile(
title: Text(listenable.controller.text),
onTap: () {
listenable.controller.text = "after click";
},
),
ListTile(
title: Text(listenable.value?.value ?? ""),
onTap: () {
listenable.value?.value = Random().nextInt(100).toString();
},
)
],
),
);
}
}
更多关于Flutter事件监听插件katana_listenables的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter事件监听插件katana_listenables的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,以下是一个关于如何在Flutter项目中使用katana_listenables
插件进行事件监听的示例代码。katana_listenables
是一个允许在Flutter应用中轻松创建和监听全局事件的插件。
首先,你需要在你的pubspec.yaml
文件中添加katana_listenables
依赖:
dependencies:
flutter:
sdk: flutter
katana_listenables: ^最新版本号 # 请替换为实际的最新版本号
然后运行flutter pub get
来安装依赖。
接下来,我们来看一个具体的代码示例。
1. 创建一个事件类
首先,我们需要定义一个事件类。这个类可以包含任何你想传递的数据。
// event.dart
class MyCustomEvent {
final String message;
MyCustomEvent({required this.message});
}
2. 设置事件监听器
在你的主应用文件(通常是main.dart
)中,设置事件监听器。
import 'package:flutter/material.dart';
import 'package:katana_listenables/katana_listenables.dart';
import 'event.dart';
void main() {
// 初始化KatanaListenables
KatanaListenables.init();
// 监听自定义事件
KatanaListenables.listen<MyCustomEvent>((event) {
print('Received event: ${event.message}');
});
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('KatanaListenables Example'),
),
body: Center(
child: MyEventButton(),
),
),
);
}
}
class MyEventButton extends StatelessWidget {
@override
Widget build(BuildContext context) {
return ElevatedButton(
onPressed: () {
// 触发自定义事件
KatanaListenables.notify(MyCustomEvent(message: 'Hello, World!'));
},
child: Text('Trigger Event'),
);
}
}
3. 运行应用
现在你可以运行你的Flutter应用。当你点击按钮时,你应该会在控制台看到打印出的消息:
Received event: Hello, World!
这个示例展示了如何使用katana_listenables
插件来创建和监听全局事件。你可以根据需要在你的应用中扩展和修改这个示例。