如图最终效果:

实现步骤:
一、创建基础文件
创建test_controller.dart、test_binding.dart、test_view.dart、index.dart文件,分别对应逻辑层、依赖注入层、视图层、模块入口
路由跳转 → TestBinding 初始化 TestController → TestView 获取控制器并渲染 UI
→ 用户操作触发 Controller 方法 → Controller 更新状态 → Obx 驱动 UI 刷新
→ 页面关闭 → GetX 销毁 Controller 并调用 onClose()
(全程通过 index.dart 简化外部引用)
Dart
//test_binding.dart文件代码
import 'package:app3/views/test/test_controller.dart';
import 'package:get/get.dart';
class TestBinding extends Bindings {
@override
void dependencies() {
Get.lazyPut(() => TestController());
}
}
Dart
//index.dart代码
export 'test_binding.dart';
export 'test_controller.dart';
export 'test_view.dart';
二、test_controller.dart中写状态、增删改查方法
Dart
//test_controller.dart
import 'package:flutter/material.dart';
import 'package:get/get.dart';
class TestController extends GetxController {
@override
void onInit() {
super.onInit();
print('初始化生命周期函数:$todoList');
// 使用 ever 监听 todoList 的变化
ever(todoList, (newValue) {
print("todoList 变化了,新值:$newValue");
});
}
@override
void onReady() {
super.onReady();
print('UI 首次构建完成:$todoList');
}
@override
void onClose() {
super.onClose();
print('页面关闭:$todoList');
}
final RxList<Map<String, dynamic>> todoList = <Map<String, dynamic>>[
{'title': '吃饭', 'isDone': true},
{'title': '睡觉', 'isDone': false},
{'title': '打游戏', 'isDone': false},
{'title': '学习', 'isDone': false},
{'title': '看电影', 'isDone': false},
{'title': '看小说', 'isDone': false},
].obs;
void add(Map<String, dynamic> item) {
todoList.add(item);
}
void delete(int index) {
todoList.removeAt(index);
}
void showDeleteDialog(int index) {
Get.dialog(
AlertDialog(
title: const Text('确定要删除吗?'),
content: const Text('删除后将无法恢复'),
actions: [
TextButton(
onPressed: () {
Get.back();
},
child: const Text('取消')),
TextButton(
onPressed: () {
delete(index);
Get.back();
},
child: const Text('确定')),
],
),
);
}
void showAddDialog() {
final TextEditingController textController = TextEditingController();
Get.dialog(
AlertDialog(
title: const Text('添加待办事项'),
content: TextField(
controller: textController,
decoration: const InputDecoration(
hintText: '请输入标题',
border: OutlineInputBorder(),
),
autofocus: true,
),
actions: [
TextButton(
onPressed: () {
Get.back();
},
child: const Text('取消')),
TextButton(
onPressed: () {
if (textController.text.trim().isNotEmpty) {
add({'title': textController.text.trim(), 'isDone': false});
Get.back();
}
},
child: const Text('确定')),
],
),
);
}
void finish(int index) {
todoList[index]['isDone'] = !todoList[index]['isDone'];
todoList.refresh(); // 手动触发更新
}
}
三、test_view.dart文件视图渲染
Dart
import 'package:app3/views/test/test_controller.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
class TestView extends GetView<TestController> {
const TestView({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('todolist')),
body: Column(
children: [
Expanded(
child: Obx(() => ListView.builder(
itemCount: controller.todoList.length,
// 构建每个列表项
itemBuilder: (BuildContext context, int index) {
return ListTile(
leading: Checkbox(
value: controller.todoList[index]['isDone'],
onChanged: (value) {
controller.finish(index);
}
),
title: Text(
'${controller.todoList[index]['title']}',
style: TextStyle(
decoration: controller.todoList[index]['isDone']
? TextDecoration.lineThrough
: TextDecoration.none,
color: controller.todoList[index]['isDone']
? Colors.grey
: null,
),
),
subtitle: Text('这是第${index + 1}个条目'),
trailing: IconButton(
onPressed: () {
controller.showDeleteDialog(index);
},
icon: const Icon(Icons.delete)
),
);
},
)),
)
],
),
floatingActionButton: FloatingActionButton(
onPressed: () {
controller.showAddDialog();
},
child: const Icon(Icons.add),
),
);
}
}