Flutter可监听集合插件listenable_collections的使用
Flutter可监听集合插件listenable_collections的使用
listenable_collections
是一个Dart集合库,它提供了一些特殊的集合类,这些集合类在数据发生变化时会像 ValueNotifier
一样通知监听器。目前实现了 ListNotifier
,未来计划实现 MapNotifier
和 SetNotifier
。
主要功能
- ListNotifier: 可监听的列表,当列表中的数据发生变化时,会通知所有监听器。
- MapNotifier 和 SetNotifier: 计划中的可监听映射和集合。
使用示例
示例代码
以下是一个使用 ListNotifier
的完整示例,展示了如何创建一个可监听的列表,并在列表变化时更新UI。
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:listenable_collections/listenable_collections.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: MyHomePage(title: 'List Notifier Example'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key? key, required this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
var _list = ListNotifier<String>();
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Padding(
padding: const EdgeInsets.all(16.0),
child: SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
actionsButtonMenu,
ValueListenableBuilder<List<String>>(
valueListenable: _list,
builder: (context, value, child) => Column(
mainAxisSize: MainAxisSize.max,
crossAxisAlignment: CrossAxisAlignment.start,
children: _list.map<Widget>((value) => Text('List Item: $value')).toList(),
),
)
],
),
),
),
);
}
Row get actionsButtonMenu => Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
ElevatedButton(
onPressed: _addItem,
child: Icon(Icons.add),
),
SizedBox(width: 16.0),
ElevatedButton(
onPressed: _removeItem,
child: Icon(Icons.remove),
),
SizedBox(width: 16.0),
ElevatedButton(
onPressed: _clearAllItems,
child: Icon(Icons.delete),
),
],
);
void _addItem() {
_list.add('${_list.length}');
}
void _removeItem() {
if (_list.isNotEmpty) _list.removeLast();
}
void _clearAllItems() {
if (_list.isNotEmpty) _list.clear();
}
}
代码说明
-
导入必要的包:
import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:listenable_collections/listenable_collections.dart';
-
创建
MyApp
类:void main() { runApp(MyApp()); } class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( theme: ThemeData( primarySwatch: Colors.blue, visualDensity: VisualDensity.adaptivePlatformDensity, ), home: MyHomePage(title: 'List Notifier Example'), ); } }
-
创建
MyHomePage
类:class MyHomePage extends StatefulWidget { MyHomePage({Key? key, required this.title}) : super(key: key); final String title; @override _MyHomePageState createState() => _MyHomePageState(); }
-
创建
_MyHomePageState
类:class _MyHomePageState extends State<MyHomePage> { var _list = ListNotifier<String>(); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text(widget.title), ), body: Padding( padding: const EdgeInsets.all(16.0), child: SingleChildScrollView( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: <Widget>[ actionsButtonMenu, ValueListenableBuilder<List<String>>( valueListenable: _list, builder: (context, value, child) => Column( mainAxisSize: MainAxisSize.max, crossAxisAlignment: CrossAxisAlignment.start, children: _list.map<Widget>((value) => Text('List Item: $value')).toList(), ), ) ], ), ), ), ); } Row get actionsButtonMenu => Row( mainAxisAlignment: MainAxisAlignment.center, children: [ ElevatedButton( onPressed: _addItem, child: Icon(Icons.add), ), SizedBox(width: 16.0), ElevatedButton( onPressed: _removeItem, child: Icon(Icons.remove), ), SizedBox(width: 16.0), ElevatedButton( onPressed: _clearAllItems, child: Icon(Icons.delete), ), ], ); void _addItem() { _list.add('${_list.length}'); } void _removeItem() { if (_list.isNotEmpty) _list.removeLast(); } void _clearAllItems() { if (_list.isNotEmpty) _list.clear(); } }
关键点
- ListNotifier: 创建一个可监听的列表。
- ValueListenableBuilder: 用于构建依赖于
ValueListenable
的UI。当ListNotifier
中的数据发生变化时,ValueListenableBuilder
会自动重新构建其子部件。 - 操作按钮: 提供了添加、删除和清空列表的功能。
通过这个示例,你可以看到如何使用 listenable_collections
插件来创建可监听的集合,并在数据变化时自动更新UI。希望这个示例对你有所帮助!
更多关于Flutter可监听集合插件listenable_collections的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter可监听集合插件listenable_collections的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,以下是如何在Flutter项目中使用listenable_collections
插件来监听集合变化的示例代码。listenable_collections
是一个方便的库,它允许你将普通的集合(如List
和Map
)包装成可监听(listenable)的集合,这样你就可以在集合变化时收到通知。
首先,确保你的pubspec.yaml
文件中包含了listenable_collections
依赖:
dependencies:
flutter:
sdk: flutter
listenable_collections: ^2.0.0 # 请检查最新版本号
然后运行flutter pub get
来安装依赖。
接下来是一个简单的示例,展示如何使用ListenableList
和ListenableMap
:
import 'package:flutter/material.dart';
import 'package:listenable_collections/listenable_collections.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('Listenable Collections Example'),
),
body: MyHomePage(),
),
);
}
}
class MyHomePage extends StatefulWidget {
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
// 使用ListenableList包装一个普通的List
final ListenableList<String> _listenableList = ListenableList<String>(['Item 1', 'Item 2']);
// 使用ListenableMap包装一个普通的Map
final ListenableMap<String, int> _listenableMap = ListenableMap<String, int>({'Key 1': 1, 'Key 2': 2});
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text('ListenableList:', style: TextStyle(fontSize: 18)),
ListView.builder(
shrinkWrap: true,
itemCount: _listenableList.length,
itemBuilder: (context, index) {
return ListTile(
title: Text(_listenableList[index]),
);
},
),
SizedBox(height: 16),
Text('ListenableMap:', style: TextStyle(fontSize: 18)),
ListView.builder(
shrinkWrap: true,
itemCount: _listenableMap.keys.length,
itemBuilder: (context, index) {
final key = _listenableMap.keys.toList()[index];
final value = _listenableMap[key]!;
return ListTile(
title: Text('$key: $value'),
);
},
),
SizedBox(height: 16),
ElevatedButton(
onPressed: () {
// 添加一个新元素到ListenableList
_listenableList.add('New Item');
// 添加一个新的键值对到ListenableMap
_listenableMap['New Key'] = 100;
},
child: Text('Add Elements'),
),
],
),
);
}
@override
void initState() {
super.initState();
// 监听ListenableList的变化
_listenableList.addListener(() {
setState(() {});
});
// 监听ListenableMap的变化
_listenableMap.addListener(() {
setState(() {});
});
}
@override
void dispose() {
// 停止监听
_listenableList.removeListener(() {});
_listenableMap.removeListener(() {});
super.dispose();
}
}
在这个示例中,我们创建了一个ListenableList
和一个ListenableMap
,并使用ListView.builder
来展示它们的内容。我们添加了一个按钮,当点击按钮时,会向这两个集合中添加新元素。通过调用addListener
方法,我们在集合变化时更新UI。
注意,在dispose
方法中,我们移除了监听器,以避免内存泄漏。
这个示例展示了如何使用listenable_collections
库来监听集合的变化并在UI中反映这些变化。希望这对你有所帮助!