flutter使用getx做一个todolist

如图最终效果:

实现步骤:

一、创建基础文件

创建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),
        ),
    );
  }
}
相关推荐
liguojun202511 小时前
智慧破局:重构体育场馆的运营与体验新生态
java·大数据·人工智能·物联网·重构·1024程序员节
Yupureki1 天前
《算法竞赛从入门到国奖》算法基础:入门篇-前缀和
c语言·数据结构·c++·算法·1024程序员节
CoderYanger2 天前
动态规划算法-01背包问题:50.分割等和子集
java·算法·leetcode·动态规划·1024程序员节
CoderYanger2 天前
动态规划算法-两个数组的dp(含字符串数组):48.最长重复子数组
java·算法·leetcode·动态规划·1024程序员节
金融小师妹2 天前
美联储议息夜:基于多智能体决策分歧模型的“鹰派降息”推演
人工智能·深度学习·1024程序员节
金融小师妹2 天前
基于NLP政策文本分析与多智能体博弈模拟的FOMC决策推演:“美联储传声筒”下的利率路径分歧
大数据·人工智能·深度学习·1024程序员节
打码人的日常分享3 天前
IPD项目质量体系管理方案
大数据·运维·人工智能·信息可视化·1024程序员节
CoderYanger4 天前
动态规划算法-两个数组的dp(含字符串数组):42.不相交的线
java·算法·leetcode·动态规划·1024程序员节
CoderYanger4 天前
动态规划算法-两个数组的dp(含字符串数组):43.不同的子序列
java·算法·leetcode·动态规划·1024程序员节
CoderYanger5 天前
动态规划算法-两个数组的dp(含字符串数组):41.最长公共子序列(模板)
java·算法·leetcode·动态规划·1024程序员节