首页 > 解决方案 > 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

标签: fluttersqlitedartintellij-ideadart-null-safety

解决方案


推荐阅读