flutter sqflite Todo

在这里插入图片描述

main.dart

import 'package:flutter/material.dart';
import 'package:todo/screens/homepage.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  // var db = DatabaseConnect();
  // // 插入一条简单的代办事项
  // await db.insertTodo(Todo(
  //     id: 1,
  //     title: '这是一条简单的代办事项 ',
  //     creationDate: DateTime.now(),
  //     isChecked: false));
  // print(await db.getTodo());
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const HomePage(),
    );
  }
}

db_model.dart

import 'package:path/path.dart';
import 'package:sqflite/sqflite.dart';
import 'package:todo/models/todo_model.dart';

class DatabaseConnect {
  Database? _database;

  // 创建getter 并打开数据库链接
  Future<Database> get database async {
    // 这是数据库的位置
    final dbpath = await getDatabasesPath();
    // 这是数据库的名称
    const dbname = 'todo.db';
    // 这是数据库的路径
    final path = join(dbpath, dbname);
    // 打开数据库链接
    _database = await openDatabase(path, version: 1, onCreate: _createDB);

    // 我们将分别创建数据库链接
    return _database!;
  }

  // _create db 方法
  // 在我们的数据库中创建表
  Future<void> _createDB(Database db, int version) async {
    // 确保我们在表中创建的列与todo_model字段匹配。
    await db.execute('''
    CREATE TABLE todo(
      id INTEGER PRIMARY KEY AUTOINCREMENT,
      title TEXT,
      creationDate TEXT,
      isChecked INTEGER
    )
    ''');
  }

  // 函数向数据库中添加数据
  Future<void> insertTodo(Todo todo) async {
    // 得到数据库链接
    final db = await database;
    // 插入代办事项
    await db.insert(
      'todo', // 表名
      todo.toMap(), // 我们这todo_model中创建的函数
      conflictAlgorithm: ConflictAlgorithm.replace, //去重
    );
  }

  Future<void> deleteTodo(Todo todo) async {
    final db = await database;
    // 从数据库中按照待办事项的id将其删除
    await db.delete(
      'todo',
      where: 'id == ?', // 此条件将检查todo列表中的id
      whereArgs: [todo.id],
    );
  }

  // 这个函数从数据库中获取全部待办事项
  Future<List<Todo>> getTodo() async {
    final db = await database;
    // 查询数据库并将待办事项保存为映射列表
    List<Map<String, dynamic>> items = await db.query(
      'todo',
      orderBy: 'id DESC', //将按照id进行降序排序
      // 所以最新的代办事项将显示在顶部
    );
    return List.generate(
      items.length,
      (index) => Todo(
        id: items[index]['id'],
        title: items[index]['title'],
        //现在是文本格式。我们把它转换成dateTime格式
        creationDate: DateTime.parse(items[index]['creationDate']),
        // 这将把integer转换为bool形式
        isChecked: items[index]['isChecked'] == 1 ? true : false,
      ),
    );
  }
}

todo_model.dart

class Todo {
  int? id;
  final String title;
  DateTime creationDate;
  bool isChecked;

  // 创建构造函数
  Todo({
    this.id,
    required this.title,
    required this.creationDate,
    required this.isChecked,
  });

  // 为了将数据保存在数据库中,我们需要将它转换为map形式,所以创建下面这个函数
  Map<String, dynamic> toMap() {
    return {
      'id': id,
      'title': title,
      'creationDate': creationDate.toString(),
      'isChecked': isChecked ? 1 : 0,
    };
  }

  // 这个函数只用于测试
  @override
  String toString() {
    return 'Todo(id:$id,title:$id,creationDate:$creationDate,isChecked:$isChecked)';
  }
}

homepage.dart

import 'package:flutter/material.dart';
import 'package:todo/models/db_model.dart';
import 'package:todo/models/todo_model.dart';
import 'package:todo/widgets/todo_list.dart';
import 'package:todo/widgets/user_input.dart';

class HomePage extends StatefulWidget {
  const HomePage({Key? key}) : super(key: key);

  @override
  State<HomePage> createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  //我们必须在这里创建函数,两个小部件可以在这里进行通信
  // 创建一个数据库对象,以便访问数据库函数
  var db = DatabaseConnect();

  // 添加待办事项的函数
  void addItem(Todo todo) async {
    await db.insertTodo(todo);
    setState(() {});
  }

  // 删除待办事项函数
  void deleteItem(Todo todo) async {
    await db.deleteTodo(todo);
    setState(() {});
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Todo app'),
        centerTitle: true,
      ),
      body: Column(
        children: [
          TodoList(
            deleteFunction: deleteItem,
            insertFunction: addItem,
          ),
          UserInput(insertFunction: addItem),
        ],
      ),
    );
  }
}

user_input.dart

import 'package:flutter/material.dart';
import 'package:todo/models/todo_model.dart';

class UserInput extends StatelessWidget {
  var textController = TextEditingController();
  final Function insertFunction; // 他是接收addItems的函数

  UserInput({required this.insertFunction, Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Container(
      // color: const Color(0xffeab5ff),
      padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 8),
      child: Row(
        children: [
          // 这是输入框
          Expanded(
              child: Container(
            decoration: BoxDecoration(
                borderRadius: BorderRadius.circular(10),
                border: Border.all(width: 2.0, color: const Color(0xff8f8f8f))),
            padding: const EdgeInsets.symmetric(horizontal: 5),
            child: TextField(
              controller: textController,
              decoration: const InputDecoration(
                hintText: 'add new todo',
                border: InputBorder.none,
              ),
            ),
          )),
          const SizedBox(width: 10),
          GestureDetector(
            onTap: () {
              var myTodo = Todo(
                  title: textController.text,
                  creationDate: DateTime.now(),
                  isChecked: false);
              insertFunction(myTodo);
            },
            child: Container(
              decoration: BoxDecoration(
                  color: Colors.lightBlue,
                  borderRadius: BorderRadius.circular(5)),
              padding: const EdgeInsets.symmetric(
                horizontal: 20,
                vertical: 10,
              ),
              child: const Text(
                'Add',
                style: TextStyle(
                  color: Colors.white,
                  fontWeight: FontWeight.bold,
                ),
              ),
            ),
          )
        ],
      ),
    );
  }
}

todo_card.dart

import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
import 'package:todo/models/todo_model.dart';

class TodoCard extends StatefulWidget {
  // 创建属性
  final int id;
  final String title;
  final DateTime creationDate;
  bool isChecked;
  final Function insertFunction;
  final Function deleteFunction;

  TodoCard(
      {Key? key,
      required this.id,
      required this.title,
      required this.isChecked,
      required this.creationDate,
      required this.insertFunction, // 它将处理复选框的变化
      required this.deleteFunction}) // 它将处理删除按钮
      : super(key: key);

  @override
  State<TodoCard> createState() => _TodoCardState();
}

class _TodoCardState extends State<TodoCard> {
  @override
  Widget build(BuildContext context) {
    var anotherTodo = Todo(
      id: widget.id,
      title: widget.title,
      creationDate: widget.creationDate,
      isChecked: widget.isChecked,
    );
    return Card(
      child: Row(
        children: [
          Container(
            margin: const EdgeInsets.symmetric(horizontal: 15, vertical: 10),
            child: Checkbox(
              value: widget.isChecked,
              onChanged: (bool? value) {
                setState(() {
                  widget.isChecked = value!;
                });
                // 修改其他todo的isCheck值
                anotherTodo.isChecked = value!;
                // 向数据库中插入
                widget.insertFunction(anotherTodo);
              },
            ),
          ),
          Expanded(
              child: Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              Text(
                widget.title,
                style:
                    const TextStyle(fontSize: 15, fontWeight: FontWeight.bold),
              ),
              const SizedBox(height: 5),
              Text(
                DateFormat('dd MMM yyyy - hh:mm aa').format(widget.creationDate),
                style: const TextStyle(
                    fontWeight: FontWeight.bold,
                    fontSize: 16,
                    color: Color(0xff8f8f8f)),
              ),
            ],
          )),
          IconButton(
              onPressed: () {
                widget.deleteFunction(anotherTodo);
              },
              icon: const Icon(Icons.close))
        ],
      ),
    );
  }
}

todo_list.dart

import 'package:flutter/material.dart';
import 'package:todo/models/db_model.dart';
import 'package:todo/widgets/todo_card.dart';

class TodoList extends StatelessWidget {
  // 创建一个数据库连接对象
  // 要向下传递到todocard,首先我们的待办事项管理员必须接收这些函数
  final Function insertFunction;
  final Function deleteFunction;
  var db = DatabaseConnect();

  TodoList(
      {Key? key, required this.insertFunction, required this.deleteFunction})
      : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Expanded(
        child: FutureBuilder(
      future: db.getTodo(),
      initialData: const [],
      builder: (BuildContext context, AsyncSnapshot<List> snapshot) {
        var data = snapshot.data;
        var datalength = data!.length;
        return datalength == 0
            ? const Center(
                child: Text("no data found"),
              )
            : ListView.builder(
                itemCount: datalength,
                itemBuilder: (context, i) => TodoCard(
                      id: data[i].id,
                      title: data[i].title,
                      isChecked: data[i].isChecked,
                      creationDate: data[i].creationDate,
                      insertFunction: insertFunction,
                      deleteFunction: deleteFunction,
                    ));
      },
    ));
  }
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值