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),
        ),
    );
  }
}
相关推荐
开开心心就好8 天前
内存清理软件灵活设置,自动阈值快捷键清
运维·服务器·windows·pdf·harmonyos·risc-v·1024程序员节
学传打活9 天前
【边打字.边学昆仑正义文化】_5_宇宙物种创造简史(1)
微信公众平台·1024程序员节·汉字·昆伦正义文化
xcLeigh10 天前
打破机房围墙:VMware+cpolar构建跨网络虚拟实验室
vmware·内网穿透·cpolar·实验室·远程访问·1024程序员节
开开心心就好11 天前
免费轻量电子书阅读器,多系统记笔记听书
linux·运维·服务器·安全·ddos·可信计算技术·1024程序员节
unable code12 天前
流量包取证-大流量分析
网络安全·ctf·misc·1024程序员节·流量包取证
开开心心就好12 天前
实用PDF擦除隐藏信息工具,空白处理需留意
运维·服务器·windows·pdf·迭代器模式·桥接模式·1024程序员节
unable code13 天前
浏览器取证-[GKCTF 2021]FireFox Forensics
网络安全·ctf·misc·1024程序员节·浏览器取证
unable code14 天前
内存取证-[安洵杯 2019]Attack
网络安全·ctf·misc·1024程序员节·内存取证
unable code14 天前
CTF-SPCS-Forensics
网络安全·ctf·misc·1024程序员节·取证