不保存颤音开关值为SQFLITE数据库
我完全是sqlite
和flutter
的初学者。我试图为我的flutter创建本地数据库
进行应用。因此,我观看了一些YouTube视频,并开始使用Flutter sqflite
插件来实现数据库。一切都很好,因为我所做的只是复制键入You Tubers代码,直到我必须在布尔值的代码中添加额外的参数,以跟踪任务的状态(例如完成任务是否完成)。我使用int
值来保存bool
,而sqlite
不支持boolean
值。我使用了两个函数
,一个用于更新文本
,另一个用于更新Switch> Switch
值。
其次,当我点击开关时,它会触发list
中的所有开关。我也想解决这个问题。
部件的模型类
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,
};
}
}
任务数据库Helper类
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,
},
);
}
}
HOMESCREEN小
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;
});
},
),
),
);
}
}
I am a completely a beginner to sqlite
and flutter
. I was trying to create a local database
to my flutter to do app. So I watched some youtube videos and started to implementing a database using flutter sqflite
plugin. Everything worked fine because all I did was copy typing the you tubers code, until I had to add an extra parameter to the code which is a boolean, in order to track the status of the task (like done the task or not). I used an int
value to save the bool
, while sqlite
does not supports boolean
values. I used two functions
, one to update the text
and the other to update the switch
value.
And secondly when I tap on a switch it triggers all the switches in the list
. I want to solve that issue as well.
Model class for the Task
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
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,
},
);
}
}
HomeScreen widget
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;
});
},
),
),
);
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我找到了答案:(如果有人有同样的问题)
我从材料应用程序小部件中删除了bool
isdone
,而不是将Switchval
分配给该bool
我将其分配给数据库的task.isdone
值。为避免Switch的自动触发器,我将taskdb
解析到updateisdone
函数
...
I found the answer: (in case of if someone had the same question)
I removed the bool
isDone
from the material app widget, and instead of assigning the switchval
to thatbool
I assigned it to database'stask.isDone
value. To avoid switch's auto trigger, I parsed theTaskdb
to theupdateIsDone
function
...