列表磁贴按钮在按下另一个按钮后更改状态

List tile button changes state after pressing another button

有一个带有列表图块的抽屉,其中包含选中所有按钮和取消选中所有按钮,当我单击选中所有按钮时,它应该选中所有列表项的复选框,但 UI 仅在之后更改或更新我点击任何其他按钮,取消选中按钮也会产生同样的问题。

drawer: Drawer(
    child: Obx(() => ListView(
          padding: EdgeInsets.zero,
          children: <Widget>[
            UserAccountsDrawerHeader(
              decoration: BoxDecoration(
                color: (Get.isDarkMode) ? Colors.black26 : Colors.grey[300],
              ),
              accountName: Text('Reminders',
                  style: TextStyle(
                    fontSize: 30.0,
                    color: Theme.of(context).textTheme.headline1!.color,
                  )),
              currentAccountPicture: CircleAvatar(
                  backgroundColor: Colors.white,
                  child: Image(
                    image: AssetImage("assets/App_icon.png"),
                  )),
              accountEmail: null,
            ),
            ListTile(
              title: Text("Check all",
                  style: TextStyle(
                      fontSize: 17.0,
                      color: Theme.of(context).textTheme.headline1!.color)),
              leading: Icon(Icons.check_box),
              onTap: () {
                checkAll();
              },
            ),
            ListTile(
              title: Text("Uncheck all",
                  style: TextStyle(
                      fontSize: 17.0,
                      color: Theme.of(context).textTheme.headline1!.color)),
              leading: Icon(Icons.check_box_outline_blank),
              onTap: () {
                unCheckAll();
              },
            ),
            ListTile(
              title: Text(
                (Get.isDarkMode)
                    ? 'Change theme:  light'
                    : 'change theme:  dark',
                style: TextStyle(
                    fontSize: 17.0,
                    color: Theme.of(context).textTheme.headline1!.color),
              ),
              leading: Icon(Icons.color_lens_sharp),
              onTap: () {
                if (Get.isDarkMode) {
                  Get.changeThemeMode(ThemeMode.light);
                } else {
                  Get.changeThemeMode(ThemeMode.dark);
                }
              },
            ),
            ListTile(
              title: Text(
                "Delete all",
                style: TextStyle(
                    fontSize: 17.0,
                    color: Theme.of(context).textTheme.headline1!.color),
              ),
              leading: Icon(Icons.delete),
              onTap: () {
                todoController.todos.clear();
              },
            ),
            ListTile(
              title: Text(
                "No of tasks:  ${todoController.todos.length}",
                style: TextStyle(
                    fontSize: 20,
                    color: Theme.of(context).textTheme.headline1!.color),
              ),
              onTap: () {},
            ),
          ],
        )),

选中所有和取消选中所有功能:

void checkAll() {
  TodoController todoController = Get.put(TodoController());
  for (var i = 0; i < todoController.todos.length; i++) {
  todoController.todos[i].done = true;
 }
 GetStorage().write('todos', todoController.todos.toList());
}

void unCheckAll() {
 TodoController todoController = Get.put(TodoController());
 for (var i = 0; i < todoController.todos.length; i++) {
   todoController.todos[i].done = false;
 }
 GetStorage().write('todos', todoController.todos.toList());
}

虽然看起来很奇怪,但这样做会解决它:

.... 
todoController.todos.assignAll(todoController.todos.toList());
GetStorage().write('todos', todoController.todos.toList());

为什么?

假设 todoController.todos 是一个 RxList,更改列表中各个元素的属性对基础流没有影响。因此,尽管更改了值,它也不会触发 Obx.

上的重建

但是做类似 todoController.todos.assignAll(todoController.todos.toList()); 的事情实际上改变了 RxList 的底层 stream/value。从而触发重建。

当使用 Rxobservables 时,请始终牢记 Obx/GetX 只会,并且只会在以下情况下触发重建Rx/Observable 的实际 value 已更改。 类似 todoController.todos[i].done = true; 的意思是改变 idone 属性 的值 RxList而不是实际 RxList 的值。 assignAll 做到了。

同样适用于其他 Rxs。 假设下面是SomeModelclass的一个Rx对象:

final someModel= SomeModel().obs;

做类似的事情:

someModel.value.someProperty = someValue;

不会触发 UI 重建,但会执行如下操作:

 someModel.value.someProperty = someValue;

  someModel.value = someModel.value;

会。

但这有点奇怪对吧? 在那种情况下,像 copyWith 实用方法这样的东西可能会有用。