flutter - Null 值正在保存,而不是 Flutter 中输入的值
问题描述
当我调用文件中的getItems()
方法database_client.dart
(检索所有项目名称)时,我收到一个空值......所以基本上我在这里只处理两个函数,它们是saveItem()
和getItems()
。但是 itemName 作为空值存储在 db 中,我不知道它为什么将它作为空值......我的代码中没有错误,但问题是我收到的 _itemName_ 和 _dateCreated 字段的空值是存在于 nodo_item.dart 文件中。
我将把我的整个项目代码给你,这样你就可以在这里轻松地找出问题所在。
主要.dart
import 'package:flutter/material.dart';
import 'package:no_to_do_app/ui/home.dart';
void main() => runApp(new MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new MaterialApp(
debugShowCheckedModeBanner: false,
title: 'NotoDo',
home: new Home(),
);
}
}
主页.dart
import 'package:flutter/material.dart';
import 'package:no_to_do_app/ui/notodo_screen.dart';
class Home extends StatelessWidget {
const Home({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: Text('NoToDo'),
backgroundColor: Colors.black54,
),
body: new NoToDoScreen(
)
);
}
}
nodo_item.dart
import 'package:flutter/material.dart';
class NoDoItem extends StatelessWidget {
late String? _itemName;
late String? _dateCreated;
int? _id;
NoDoItem( this._itemName , this._dateCreated, {Key? key}) : super(key: key);
NoDoItem.map(dynamic obj, {Key? key}) : super(key: key)
{
_itemName = obj['ItemName'];
_dateCreated = obj['DateCreated'];
_id = obj['id'];
}
String? get itemName => _itemName;
String? get dateCreated => _dateCreated;
int? get id => _id;
Map<String , dynamic>toMap()
{
var map = <String , dynamic>{};
map['ItemName'] = _itemName;
map['DateCreated'] = _dateCreated;
/*if(_id !=null)
{
map['id'] = _id;
}*/
map['id'] = _id;
return map;
}
NoDoItem.fromMap(Map<String , dynamic>map, {Key? key}) : super(key: key)
{
_itemName = map['ItemName'];
_dateCreated = map['DateCreated'];
_id = map['id'];
}
@override
Widget build(BuildContext context) {
return Container(
margin: const EdgeInsets.all(8.0),
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(_itemName! ,
style: const TextStyle(
color: Colors.white,
fontSize: 16.5,
fontWeight: FontWeight.bold
),),
Container(
margin: const EdgeInsets.only(top: 5.0),
child: Text('Created on: $_dateCreated',
style: const TextStyle(
color: Colors.white70,
fontStyle: FontStyle.italic,
fontSize: 13.4
),),
)
],
)
);
}
}
database_client.dart
import 'dart:async';
import 'dart:io';
import 'package:flutter/cupertino.dart';
import 'package:no_to_do_app/model/nodo_item.dart';
import 'package:path_provider/path_provider.dart';
import 'package:sqflite/sqflite.dart';
import 'package:path/path.dart';
class DatabaseHelper
{
static final DatabaseHelper _instance = DatabaseHelper.private();
DatabaseHelper.private();
factory DatabaseHelper() => _instance;
final String tableName = "nodoTbl";
final String columnId = "id";
final String columnItemName = "itemName";
final String columnDateCreated = "dateCreated";
static late Database _db;
Future<Database> get database async
{
/*if(_db!=null)
{
return _db;
}*/
_db =await initDb();
return _db;
}
DatabaseHelper.internal();
initDb() async
{
Directory documentDirectory = await getApplicationDocumentsDirectory();
String path = join(documentDirectory.path, "notodo_db.db");
var ourDb= await openDatabase(path , version: 1 , onCreate: _onCreate);
return ourDb;
}
void _onCreate(Database db, int version) async
{
await db.execute(
"CREATE TABLE $tableName(id INTEGER PRIMARY KEY , $columnItemName TEXT ,$columnDateCreated TEXT)"
);
debugPrint('Table is Created');
}
Future<int> saveItem(NoDoItem item) async
{
var dbClient = await database;
int res =await dbClient.insert(tableName, item.toMap());
debugPrint(res.toString());
return res;
}
Future<List> getItems() async
{
var dbClient = await database;
var result = await dbClient.rawQuery("SELECT * FROM $tableName ORDER BY $columnItemName ASC");
return result.toList();
}
Future<int?> getCount() async
{
var dbClient = await database;
return Sqflite.firstIntValue(await dbClient.rawQuery(
"SELECT COUNT(*) FROM $tableName"
));
}
Future<NoDoItem?> getItem(int id) async{
var dbClient = await database;
var result = await dbClient.rawQuery("SELECT * FROM $tableName WHERE id=$id");
//if(result.length==0) return null;
if(result.isEmpty) return null;
return NoDoItem.fromMap(result.first);
}
Future<int> deleteItem(int id) async
{
var dbClient =await database;
return await dbClient.delete(tableName,where: "$columnId = ?", whereArgs: [id]);
}
Future<int> updateItem(NoDoItem item) async
{
var dbClient =await database;
return await dbClient.update(tableName, item.toMap(),
where: "$columnId=?", whereArgs: [item.id]);
}
Future close() async
{
var dbClient =await database;
return dbClient.close();
}
}
notodo_screen.dart
import 'package:flutter/material.dart';
import 'package:no_to_do_app/model/nodo_item.dart';
import 'package:no_to_do_app/util/database_client.dart';
class NoToDoScreen extends StatefulWidget {
const NoToDoScreen({Key? key}) : super(key: key);
@override
_NoToDoScreenState createState() => _NoToDoScreenState();
}
class _NoToDoScreenState extends State<NoToDoScreen> {
final TextEditingController _textEditingController = TextEditingController();
var db = DatabaseHelper();
@override
void initState() {
// TODO: implement initState
super.initState();
_readNotoDoItems();
}
void _hndleSubmitted(String text) async
{
_textEditingController.clear();
NoDoItem noDoItem = NoDoItem(text, DateTime.now().toIso8601String());
int savedItemId = await db.saveItem(noDoItem);
debugPrint("Item saved ID: $savedItemId");
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.black87,
body: Column(),
floatingActionButton: FloatingActionButton(
tooltip: 'Add Item',
backgroundColor: Colors.redAccent,
child: const ListTile(
title: Icon(Icons.add)
),
onPressed: _showFormDialog),
);
}
void _showFormDialog() {
var alert = AlertDialog(
content: Row(
children: [
Expanded(
child: TextField(
controller: _textEditingController,
autofocus: true,
decoration: const InputDecoration(
labelText: 'item',
hintText: "eg. Don't buy Stuff",
icon: Icon(Icons.add_circle_outline_outlined)
),
))
],
),
actions: [
TextButton(
style: ButtonStyle(
foregroundColor: MaterialStateProperty.all<Color>(Colors.blue),
),
onPressed: () {
_hndleSubmitted(_textEditingController.text);
_textEditingController.clear();
},
child: const Text("Save"),
),
TextButton(
style: ButtonStyle(
foregroundColor: MaterialStateProperty.all<Color>(Colors.blue),
),
onPressed: () => Navigator.pop(context),
child: const Text("Cancel"),)
]
);
showDialog(context: context,
builder: (_) {
return alert;
});
}
_readNotoDoItems() async
{
List items = await db.getItems();
items.forEach((item) {
NoDoItem noDoItem = NoDoItem.map(item);
print("Db items: ${noDoItem.itemName}");
});
}
}
运行项目后我得到的输出:
Performing hot restart...
Syncing files to device Android SDK built for x86...
Restarted application in 8,386ms.
I/flutter ( 3831): Db items: null
I/flutter ( 3831): Db items: null
I/flutter ( 3831): Db items: null
I/flutter ( 3831): Db items: null
I/flutter ( 3831): Db items: null
I/flutter ( 3831): Db items: null
I/flutter ( 3831): Db items: null
I/flutter ( 3831): Db items: null
I/flutter ( 3831): Db items: null
I/flutter ( 3831): Db items: null
I/flutter ( 3831): Db items: null
D/InputConnectionAdaptor( 3831): The input method toggled cursor monitoring on
I/TextInputPlugin( 3831): Composing region changed by the framework. Restarting the input method.
W/IInputConnectionWrapper( 3831): getTextBeforeCursor on inactive InputConnection
W/IInputConnectionWrapper( 3831): getTextBeforeCursor on inactive InputConnection
D/InputConnectionAdaptor( 3831): The input method toggled cursor monitoring on
I/flutter ( 3831): 12
I/flutter ( 3831): Item saved ID: 12
解决方案
推荐阅读
- amazon-web-services - AWS Cognito 使用另一个区域发送 SMS
- xml - 我需要从 SOAP 消息中提取数据
- r - 将许多宽格式列表转换为长格式
- django - 'Tribe' 对象没有属性 'tribe_id'
- ubuntu - 使用 Certbot SSL 和允许多个根域的 NGINX 多租户配置
- javascript - 即使您在中途停止悬停,如何强制动画完成然后反转以开始悬停?
- python-3.x - ssl_client_socket_impl.cc(962) 握手失败
- ruby-on-rails - 实施 mailchimp oauth2 身份验证
- laravel - Laravel DotEnv 不读取服务器环境变量
- c# - 用于程序重构的 OOP 设计模式