You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

监控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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.01 16:44:53