列表磁贴按钮在按下另一个按钮后更改状态
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。从而触发重建。
当使用 Rx 或 observables 时,请始终牢记 Obx/GetX
只会,并且只会在以下情况下触发重建Rx/Observable 的实际 value
已更改。
类似 todoController.todos[i].done = true;
的意思是改变 i 的 done
属性 的值 RxList而不是实际 RxList 的值。 assignAll
做到了。
同样适用于其他 Rxs。
假设下面是SomeModel
class的一个Rx
对象:
final someModel= SomeModel().obs;
做类似的事情:
someModel.value.someProperty = someValue;
不会触发 UI 重建,但会执行如下操作:
someModel.value.someProperty = someValue;
someModel.value = someModel.value;
会。
但这有点奇怪对吧?
在那种情况下,像 copyWith
实用方法这样的东西可能会有用。
有一个带有列表图块的抽屉,其中包含选中所有按钮和取消选中所有按钮,当我单击选中所有按钮时,它应该选中所有列表项的复选框,但 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。从而触发重建。
当使用 Rx 或 observables 时,请始终牢记 Obx/GetX
只会,并且只会在以下情况下触发重建Rx/Observable 的实际 value
已更改。
类似 todoController.todos[i].done = true;
的意思是改变 i 的 done
属性 的值 RxList而不是实际 RxList 的值。 assignAll
做到了。
同样适用于其他 Rxs。
假设下面是SomeModel
class的一个Rx
对象:
final someModel= SomeModel().obs;
做类似的事情:
someModel.value.someProperty = someValue;
不会触发 UI 重建,但会执行如下操作:
someModel.value.someProperty = someValue;
someModel.value = someModel.value;
会。
但这有点奇怪对吧?
在那种情况下,像 copyWith
实用方法这样的东西可能会有用。