Flutter可监听集合插件listenable_collections的使用

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

Flutter可监听集合插件listenable_collections的使用

listenable_collections 是一个Dart集合库,它提供了一些特殊的集合类,这些集合类在数据发生变化时会像 ValueNotifier 一样通知监听器。目前实现了 ListNotifier,未来计划实现 MapNotifierSetNotifier

主要功能

  • ListNotifier: 可监听的列表,当列表中的数据发生变化时,会通知所有监听器。
  • MapNotifierSetNotifier: 计划中的可监听映射和集合。

使用示例

示例代码

以下是一个使用 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();
  }
}

代码说明

  1. 导入必要的包:

    import 'package:flutter/foundation.dart';
    import 'package:flutter/material.dart';
    import 'package:listenable_collections/listenable_collections.dart';
    
  2. 创建 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'),
        );
      }
    }
    
  3. 创建 MyHomePage:

    class MyHomePage extends StatefulWidget {
      MyHomePage({Key? key, required this.title}) : super(key: key);
    
      final String title;
    
      @override
      _MyHomePageState createState() => _MyHomePageState();
    }
    
  4. 创建 _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

1 回复

更多关于Flutter可监听集合插件listenable_collections的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是如何在Flutter项目中使用listenable_collections插件来监听集合变化的示例代码。listenable_collections是一个方便的库,它允许你将普通的集合(如ListMap)包装成可监听(listenable)的集合,这样你就可以在集合变化时收到通知。

首先,确保你的pubspec.yaml文件中包含了listenable_collections依赖:

dependencies:
  flutter:
    sdk: flutter
  listenable_collections: ^2.0.0 # 请检查最新版本号

然后运行flutter pub get来安装依赖。

接下来是一个简单的示例,展示如何使用ListenableListListenableMap

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中反映这些变化。希望这对你有所帮助!

回到顶部