Flutter:如何更新单个列表项的 ValueNotifier

2024-01-15

我有一个列表生成器,用于创建包含内容的卡片。在这张卡中,我有一个按钮和文本小部件。基本上,我想在按下按钮时更新文本小部件。我尝试使用 ValueNotifier 并且它有效。但它会更新每个列表项的值。

这是主要功能:

我创建了 ValueNotifier 变量

class SelectedOrganizationStructure extends StatefulWidget {
  static ValueNotifier<String> lastLoginDate = ValueNotifier('Last login');
  final List<OrganizationUnitEntity> organizationStructure;
  const SelectedOrganizationStructure(this.organizationStructure, {Key? key})
      : super(key: key);

  @override
  State<SelectedOrganizationStructure> createState() =>
      _SelectedOrganizationStructureState();
}

我将其设置为文本小部件Text(SelectedOrganizationStructure.lastLoginDate.value),当我按下按钮时,我将其值设置为当前日期,如下所示:

final _dateTime = DateTime.now();
final _loginDate = DateFormat('dd.MM HH:mm').format(_dateTime).toString();

onTap: () {
  SelectedOrganizationStructure.lastLoginDate.value = _loginDate
},

我之前说过,这会设置列表生成器中所有卡片项目的当前日期。我怎样才能让它只更新按下女巫按钮的卡片?


问题

ValueNotifier仅当值更改时通知其侦听器。但是,如果该值为List像这样:

final myListNotifier = ValueNotifier<List<String>>([]);

像这样更改单个项目:

myListNotifier.value.add('Hello');

不会通知侦听器,因为列表本身没有更改。仅列表中的一项发生了变化。对于 Dart 来说,列表是对列表对象的引用。每次更改列表内容时,该引用都不会更改。

有几种解决方案。

创建新列表

如果您使用更新的内容创建新列表,则更改value通知程序中将导致它通知其侦听器。下面演示了这一点:

final newList = myListNotifier.value.toList();
newList.add('Hello');
myListNotifier.value = newList;

这很有效,而且对于大多数情况来说可能没问题。毕竟,在大多数应用程序中,您不会处理非常长的列表,因此制作副本并不是什么大问题。

然而,还有另一种选择。

自己通知听众

Since ValueNotifier延伸ChangeNotifier你可以打电话notifyListeners你自己。然而,这种方法有一个protected注释,这意味着您只能从子类中调用它。

以下是创建自定义子类的示例:

class MyStateManager {
  final myListNotifier = ListNotifier();

  void send(String text) {
    myListNotifier.add(text);
  }
}

class ListNotifier extends ValueNotifier<List<String>> {
  ListNotifier() : super([]);

  void add(String listItem) {
    value.add(listItem);
    notifyListeners();            // here
  }
}

In your add方法中,您更新列表的内容(无需创建新列表),然后手动通知侦听器,就像在ChangeNotifier.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Flutter:如何更新单个列表项的 ValueNotifier 的相关文章