Не сохранять значение переключателя флаттера в базе данных sqflite

Я совсем новичок в sqlite и flutter. Я пытался создать локальный database для своего приложения flutter to do. Поэтому я посмотрел несколько видеороликов на YouTube и начал реализовывать базу данных с помощью плагина flutter sqflite. Все работало нормально, потому что все, что я сделал, это скопировал код you tubers, пока мне не пришлось добавить в код дополнительный параметр, который является логическим, чтобы отслеживать статус задачи (например, выполнил задачу или нет). Я использовал значение int для сохранения bool, а sqlite не поддерживает значения boolean. Я использовал два functions, один для обновления text, а другой для обновления значения switch.

А во-вторых, когда я нажимаю на переключатель, срабатывают все переключатели в list. Я тоже хочу решить этот вопрос.

Не сохранять значение переключателя флаттера в базе данных sqflite

Класс модели для задачи

class Tasksdb {
  final int? id;
  final String taskName;
  bool isDone;

  Tasksdb({
    this.id,
    required this.taskName,
    required this.isDone,
  });

  factory Tasksdb.fromMap(Map<String, dynamic> json) => Tasksdb(
      id: json['id'],
      taskName: json['taskName'],
      isDone: (json['isDone'] as int) == 0 ? false : true);

  Map<String, dynamic> toMap() {
    return {
      'id': id,
      'taskName': taskName,
      'isDone': isDone,
    };
  }
}  

Класс DatabaseHelper

 class DatabaseHelper {
  DatabaseHelper._privateConstructor();
  static final DatabaseHelper instance = DatabaseHelper._privateConstructor();

  static Database? _database;
  Future<Database> get database async => _database ??= await _initDatabase();

  Future<Database> _initDatabase() async {
    Directory documentsDirectory = await getApplicationDocumentsDirectory();
    String path = join(documentsDirectory.path, 'tasks.db');
    return await openDatabase(
      path,
      version: 1,
      onCreate: _onCreate,
    );
  }

  Future _onCreate(Database db, int version) async {
    await db.execute('''
      CREATE TABLE IF NOT EXISTS "taskstable" (
    "id"    INTEGER,
    "taskName"  TEXT,
    "isDone"    INTEGER NOT NULL DEFAULT 0,
    PRIMARY KEY("id" AUTOINCREMENT)
);
      ''');
  }

  Future<List<Tasksdb>> getTasks() async {
    Database db = await instance.database;
    var tasksQuery = await db.query(
      'taskstable',
    );
    List<Tasksdb> taskList = tasksQuery.isNotEmpty
        ? tasksQuery.map((c) => Tasksdb.fromMap(c)).toList()
        : [];
    return taskList;
  }

  Future<int> add(Tasksdb task) async {
    Database db = await instance.database;
    return await db.insert('taskstable', {
      'id': task.id,
      'taskName': task.taskName,
      'isDone': 0,
    });
  }


  Future<int> update(Tasksdb task) async {
    Database db = await instance.database;
    return await db.update(
      'taskstable',
      task.toMap(),
      where: "id = ?",
      whereArgs: [task.id],
    );
  }

  Future<int> updateIsDone(bool isDoneTodb) async {
    Database db = await instance.database;
    return await db.update(
      'taskstable',
      {
        'isDone': isDoneTodb == true ? 1 : 0,
      },
    );
  }
}

Виджет главного экрана

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

  @override
  _SqliteAppState createState() => _SqliteAppState();
}

class _SqliteAppState extends State<SqliteApp> {
  int? selectedId;
  final textController = TextEditingController();
  bool isDone = false;

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: TextField(
            controller: textController,
          ),
        ),
        body: Center(
          child: FutureBuilder<List<Tasksdb>>(
              future: DatabaseHelper.instance.getTasks(),
              builder: (BuildContext context,
                  AsyncSnapshot<List<Tasksdb>> snapshot) {
                if (!snapshot.hasData) {
                  return const Center(child: Text('Loading...'));
                }
                return snapshot.data!.isEmpty
                    ? const Center(child: Text('No tasks in List.'))
                    : ListView(
                        children: snapshot.data!.map((task) {
                          return Center(
                            child: Card(
                              color: selectedId == task.id
                                  ? Colors.green
                                  : Colors.yellow,
                              child: ListTile(
                                trailing: Switch(   //the problem is here, doesn't save to db
                                    value: isDone,
                                    onChanged: (val) async {
                                      setState(() {
                                        isDone = val;
                                      });
                                      await DatabaseHelper.instance
                                          .updateIsDone(
                                        isDone,
                                      );
                                    }),
                                title: Text(task.taskName),
                                onTap: () {
                                  setState(() {
                                    if (selectedId == null) {
                                      textController.text = task.taskName;
                                      selectedId = task.id;
                                    } else {
                                      textController.text = 'add something';
                                      selectedId = null;
                                    }
                                  });
                                },
                              ),
                            ),
                          );
                        }).toList(),
                      );
              }),
        ),
        floatingActionButton: FloatingActionButton(
          onPressed: () async {
            await DatabaseHelper.instance.add(
              Tasksdb(
                taskName: textController.text,
                isDone: false,
              ),
            );
            setState(() {
              textController.clear();
              selectedId = null;
            });
          },
        ),
      ),
    );
  }
}
ReactJs | Supabase | Добавление данных в базу данных
ReactJs | Supabase | Добавление данных в базу данных
Это и есть ваш редактор таблиц в supabase.👇
0
0
21
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Я нашел ответ: (на случай, если у кого-то возник такой же вопрос) Я удалил логическое значение isDone из виджета приложения материалов и вместо того, чтобы назначить переключатель val этому bool, я присвоил его значению базы данных task.isDone. Чтобы избежать автоматического срабатывания переключателя, я разобрал Taskdb на updateIsDonefunction

Future<int> updateIsDone(Tasksdb task, bool isDoneTodb) async {
    Database db = await instance.database;
    return await db.update(
        'taskstable',
        {
          'isDone': isDoneTodb == true ? 1 : 0,
        },
        where: "id = ?",
        whereArgs: [task.id]);
  }

...

Switch(
     value: task.isDone,
     onChanged: (val) async {
            setState(() {
                 task.isDone = val;
            });
     await DatabaseHelper.instance
     .updateIsDone(task, task.isDone);
       }); 

Другие вопросы по теме