valuenotifier 不更新更新列表的小部件

Nim*_*tar 2 dart flutter

import 'package:flutter/material.dart';
import '../../Data/Globalvariable.dart' as global;

class MenuBar extends StatefulWidget {
  final key = UniqueKey();
  // final pin;
  // MenuBar({this.pin='112'});
  @override
  _MenuBarState createState() {
    return _MenuBarState();
  }
}

class _MenuBarState extends State<MenuBar> {
  ValueNotifier<List<String>> st = ValueNotifier(global.pincode);
  Widget total() {
    return ListView.builder(
      itemCount: global.pincode.length,
      itemBuilder: (context, index) {
        final item = global.pincode[index];
        return Dismissible(
          key: UniqueKey(),
          onDismissed: (direction) {
            setState(() {
              global.pincode.removeAt(index);
            });
            ScaffoldMessenger.of(context)
                .showSnackBar(SnackBar(content: Text('$item Removed')));
          },
          background: Container(color: Colors.red),
          child: ListTile(
            title: Text(item),
          ),
        );
      },
    );
  }

  @override
  Widget build(BuildContext context) {
    return ValueListenableBuilder(
      builder: (context, n, menu) {
        print(global.pincode);
        return total();
      },
      child: total(),
      valueListenable: st,
    );
  }
}
Run Code Online (Sandbox Code Playgroud)

这是我的主文件,我有一个全局文件,我所有的工作变量都在那里

Globalvariable.dart

library project.globals;
List<String> pincode = ['Select Pin','110084','110088'];
Run Code Online (Sandbox Code Playgroud)

现在,当我将数据添加到 pincode valuenotifier 中时,它应该监听它并自动更新小部件,但它没有这样做,所以我验证了使用调试控制台,当我调用 setstate 时它会更新,这是可以的,但我想在添加数据时更新小部件到我的清单

在此输入图像描述

这是为了证明我上面所说的 wigdet 正在删除时更新,但不更新添加

小智 8

如果您已经使用 ValueNotifier,则无需使用 SetState。
要更新状态,请使用:st.value = new value

因为您已经使用 ValueListenableBuilder 包装了您的子窗口小部件,所以如果 st 的值发生变化,状态将自动更改。


ValueNotifier 使用相等性来检测变化。对于 List,如果您只添加/删除列表的值,dart 编译器不会注意到任何变化。

为了解决这个问题,您需要创建一个新列表,以便 dart 编译器检测到更改。

您可以像这样更新您的代码:

return Dismissible(
  key: UniqueKey(),
  onDismissed: (direction) {
    st.value = List.from(st.value)..removeAt(index);
    ScaffoldMessenger.of(context)
        .showSnackBar(SnackBar(content: Text('$item Removed')));
  },
  background: Container(color: Colors.red),
  child: ListTile(
    title: Text(item),
  ),
);
Run Code Online (Sandbox Code Playgroud)


小智 5

为了让生活更轻松,您可以编写一个扩展 ValueNotifier<List> 的类并定义方法 add 和 remove,如下面的示例所示。然后只需使用_yourNotifier.add(newValue);所以你不需要重复List.from(st.value)..removeAt(index)等等。

class ValueNotifierList<T> extends ValueNotifier<List<T>> {
  ValueNotifierList(List<T> value) : super(value);

  void add(T valueToAdd) {
    value = [...value, valueToAdd];
  }

  void remove(T valueToRemove) {
    value = value.where((value) => value != valueToRemove).toList();
  }
}
Run Code Online (Sandbox Code Playgroud)