监控List<T>列表及元素变更的简洁优雅实现方案
实现可监听的Dart列表(无第三方库、无封装方法)
要在Dart中实现列表添加、移除元素,以及元素修改时自动触发通知,同时不依赖第三方库、不封装专用方法,可以通过自定义List子类来实现,以下是具体方案:
一、监听列表结构变化(添加、删除、索引赋值)
通过继承dart:collection里的ListBase,重写列表的核心操作方法,在方法里嵌入通知逻辑:
import 'dart:collection'; class ListenableList<T> extends ListBase<T> { final List<T> _innerList = []; void Function()? onChanged; ListenableList({this.onChanged}); @override int get length => _innerList.length; @override set length(int newLength) { _innerList.length = newLength; _notifyChange(); } @override T operator [](int index) => _innerList[index]; @override void operator []=(int index, T value) { _innerList[index] = value; _notifyChange(); } @override void add(T element) { _innerList.add(element); _notifyChange(); } @override void addAll(Iterable<T> iterable) { _innerList.addAll(iterable); _notifyChange(); } @override bool remove(Object? element) { final result = _innerList.remove(element); if (result) _notifyChange(); return result; } @override T removeAt(int index) { final element = _innerList.removeAt(index); _notifyChange(); return element; } // 按需重写其他需要监听的方法,比如clear、insert、removeLast等 void _notifyChange() { onChanged?.call(); } }
使用示例
void main() { final myList = ListenableList<int>(onChanged: () { print('列表已修改!'); }); myList.addAll([1,2,3]); myList.add(4); // 触发通知:列表已修改! myList[1] = 0; // 触发通知:列表已修改! }
二、监听列表元素内部属性修改(针对可变对象)
你示例中var myVar = myList[2]; myVar = 3;的场景要注意:int是值类型,赋值myVar = 3只是改变了变量本身的指向,并不会修改原列表里的元素,所以这种情况没法触发列表通知。如果要监听元素内部的修改,需要把值类型包装成可变引用类型,再让列表监听每个元素的变化:
// 1. 先实现一个可监听的元素类 class NotifiableInt { int value; void Function()? onChanged; NotifiableInt(this.value); set setValue(int newValue) { value = newValue; onChanged?.call(); } } // 2. 扩展可监听列表,添加元素内部变化的监听逻辑 class DeepListenableList<T extends NotifiableInt> extends ListenableList<T> { DeepListenableList({super.onChanged}) { // 给初始化时的元素绑定监听 for (final element in _innerList) { _bindElementListener(element); } } @override void operator []=(int index, T value) { // 移除旧元素的监听 _unbindElementListener(_innerList[index]); // 给新元素绑定监听 _bindElementListener(value); super.operator []=(index, value); } @override void add(T element) { _bindElementListener(element); super.add(element); } @override void addAll(Iterable<T> iterable) { for (final element in iterable) { _bindElementListener(element); } super.addAll(iterable); } void _bindElementListener(T element) { element.onChanged = () { _notifyChange(); }; } void _unbindElementListener(T element) { element.onChanged = null; } }
使用示例
void main() { final myList = DeepListenableList<NotifiableInt>(onChanged: () { print('列表或元素已修改!'); }); myList.add(NotifiableInt(1)); myList.add(NotifiableInt(2)); myList.add(NotifiableInt(3)); final myVar = myList[2]; myVar.setValue = 3; // 触发通知:列表或元素已修改! }
内容的提问来源于stack exchange,提问作者user3262353
相关产品推荐
相关产品推荐

