我正在尝试制作一个与简单的待办事项应用程序具有基本相同机制的应用程序。我的问题是,当我尝试打开可以创建新项目/待办事项(new_project_screen)的屏幕时,应该加载一些 TextField,但它们没有。相反,会发生此错误。我尝试了 stackoverflow 的几种解决方案,但没有任何效果,我不知道为什么它不起作用。(对不起,我的英语不好,我不是本地 xD)
这是我的代码: main.dart:
import 'package:flutter/material.dart';
import 'package:leisy/surface/main_screen.dart';
void main() {
WidgetsFlutterBinding.ensureInitialized();
runApp(App());
}
class App extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Leisy',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MainScreen(),
);
}
}
main_screen.dart:
import 'package:flutter/material.dart';
import 'dart:async';
import 'package:sqflite/sqflite.dart';
import 'package:leisy/db/database_helper.dart';
import 'package:leisy/model/project.dart';
import 'package:leisy/surface/settings_screen.dart';
import 'package:leisy/surface/new_project_screen.dart';
class MainScreen extends StatefulWidget {
@override
_MainScreenState createState() => _MainScreenState();
}
class _MainScreenState extends State<MainScreen> {
DatabaseHelper databaseHelper = DatabaseHelper();
List<Project> projectList = [];
int count = 0;
@override
Widget build(BuildContext context) {
if (projectList == null) {
projectList = <Project>[];
updateListView();
}
debugPrint("Building entire main screen scaffold");
return Scaffold(
appBar: AppBar(
title: Text("Leisy"),
),
drawer: Drawer(
child: ListView(
padding: EdgeInsets.zero,
children: <Widget>[
DrawerHeader(
child: Center(
child: Text(
"Menü",
textAlign: TextAlign.center,
style: TextStyle(
color: Colors.white,
fontSize: 25,
),
),
),
decoration: BoxDecoration(color: Colors.blue),
),
ListTile(
leading: Icon(Icons.home),
title: Text('Home'),
onTap: () => {Navigator.of(context).pop()},
),
ListTile(
leading: Icon(Icons.add),
title: Text('Neues Projekt'),
onTap: () => {
Navigator.of(context).push(new MaterialPageRoute(
builder: (context) => new NewProjectScreen()))
},
),
ListTile(
leading: Icon(Icons.settings),
title: Text('Einstellungen'),
onTap: () => {
Navigator.of(context).push(
MaterialPageRoute(builder: (context) => SettingsScreen()))
},
)
],
),
),
body: getProjectListView(),
floatingActionButton: FloatingActionButton(
child: Icon(Icons.add),
onPressed: navigateToNewProject,
),
);
}
ListView getProjectListView() {
TextStyle titleStyle = Theme.of(context).textTheme.subtitle1;
return ListView.builder(
itemCount: count,
itemBuilder: (BuildContext context, int position) {
return Card(
color: Colors.white,
elevation: 2.0,
child: ListTile(
leading: CircleAvatar(
backgroundColor: Colors.blue,
),
title: Text(
this.projectList[position].name,
style: titleStyle,
),
subtitle: Text(this.projectList[position].date),
onTap: () {
debugPrint('ListTile Tapped');
//navigateToDetail() einfügen
},
),
);
});
}
void _showSnackBar(BuildContext context, String message) {
final snackBar = SnackBar(
content: Text(message),
);
ScaffoldMessenger.of(context).showSnackBar(snackBar);
}
void navigateToNewProject() async {
bool result = await Navigator.push(context, MaterialPageRoute(builder: (context) => NewProjectScreen()));
if (result == true) {
updateListView();
}
}
void updateListView() {
final Future<Database> dbFuture = databaseHelper.initDB();
dbFuture.then((database) {
Future<List<Project>> projectListFuture = databaseHelper.getProjectList();
projectListFuture.then((projectList) {
setState(() {
this.projectList = projectList;
this.count = projectList.length;
});
});
});
}
}
new_project_screen.dart:
import 'package:flutter/material.dart';
import 'package:leisy/db/database_helper.dart';
import 'package:leisy/model/project.dart';
import 'package:leisy/surface/main_screen.dart';
import 'package:leisy/surface/settings_screen.dart';
class NewProjectScreen extends StatefulWidget {
@override
_NewProjectScreenState createState() => _NewProjectScreenState();
}
class _NewProjectScreenState extends State<NewProjectScreen> {
Project project;
DatabaseHelper helper = DatabaseHelper();
TextEditingController nameController = TextEditingController();
TextEditingController dateController = TextEditingController();
TextEditingController locationController = TextEditingController();
@override
Widget build(BuildContext context) {
nameController.text = project.name;
dateController.text = project.date;
locationController.text = project.location;
return Scaffold(
appBar: AppBar(
title: Text("Neues Projekt"),
leading: IconButton(
icon: Icon(Icons.arrow_back),
onPressed: () {
Navigator.pop(context);
},
),
),
drawer: Drawer(
child: ListView(
padding: EdgeInsets.zero,
children: <Widget>[
DrawerHeader(
child: Center(
child: Text(
"Menü",
textAlign: TextAlign.center,
style: TextStyle(
color: Colors.white,
fontSize: 25,
),
),
),
decoration: BoxDecoration(color: Colors.blue),
),
ListTile(
leading: Icon(Icons.home),
title: Text('Home'),
onTap: () => {
Navigator.of(context).push(
MaterialPageRoute(builder: (context) => MainScreen()))
},
),
ListTile(
leading: Icon(Icons.add),
title: Text('Neues Projekt'),
onTap: () => {Navigator.of(context).pop()},
),
ListTile(
leading: Icon(Icons.settings),
title: Text('Einstellungen'),
onTap: () => {
Navigator.of(context).push(
MaterialPageRoute(builder: (context) => SettingsScreen()))
},
)
],
),
),
body: Padding(
padding: EdgeInsets.all(8.0),
child: ListView(
children: <Widget>[
TextField(
controller: nameController,
decoration: InputDecoration(labelText: 'Name'),
style: TextStyle(fontSize: 20),
onChanged: (value) {
setState(() {
updateName();
});
},
),
TextField(
decoration: InputDecoration(labelText: 'Datum'),
style: TextStyle(fontSize: 20),
onChanged: (value) {
setState(() {
updateDate();
});
},
),
TextField(
decoration: InputDecoration(labelText: 'Ort'),
style: TextStyle(fontSize: 20),
onChanged: (value) {
setState(() {
updateLocation();
});
},
),
Row(
children: <Widget>[
Expanded(
child: ElevatedButton(
style: ButtonStyle(
backgroundColor: MaterialStateProperty.all(
Theme.of(context).primaryColorDark),
),
child: Text('Speichern'),
onPressed: () {
setState(() {
_save();
});
},
)),
Expanded(
child: ElevatedButton(
style: ButtonStyle(
backgroundColor: MaterialStateProperty.all(
Theme.of(context).primaryColorDark),
),
child: Text('Abbrechen'),
onPressed: () {
setState(() {
_cancel();
});
},
)),
],
)
],
)
)
);
}
void _save() async {
Navigator.pop(context, true);
await helper.insertProject(project);
}
void _showSnackBar(String message) {
SnackBar snackBar = SnackBar(content: Text(message));
ScaffoldMessenger.of(context).showSnackBar(snackBar);
}
void _cancel() async {
Navigator.pop(context, true);
_showSnackBar('Vorgang abgebrochen');
}
void updateName() {
project.name = nameController.text;
}
void updateDate() {
project.date = dateController.text;
}
void updateLocation() {
project.location = locationController.text;
}
}
project.dart:
class Project {
int _id;
String _name;
String _date;
String _location;
String _personaldb;
Project(this._name, this._date, this._location, this._personaldb);
Project.withId(
this._id, this._name, this._date, this._location, this._personaldb);
int get id => _id;
String get name => _name;
String get date => _date;
String get location => _location;
String get personalDB => _personaldb;
set name(String newName) {
if (newName.length <= 63) {
this._name = newName;
}
}
set date(String newDate) {
this._date = newDate;
}
set location(String newLocation) {
this._location = newLocation;
}
set personalDB(String newPersonalDB) {
this._personaldb = newPersonalDB;
}
Map<String, dynamic> toMap() {
var map = Map<String, dynamic>();
if (id != null) {
map['id'] = _id;
}
map['name'] = _name;
map['date'] = _date;
map['location'] = _location;
map['personalDB'] = _personaldb;
return map;
}
Project.fromMapObject(Map<String, dynamic> map) {
this._id = map['id'];
this._name = map['name'];
this._date = map['date'];
this._location = map['location'];
this._personaldb = map['personalDB'];
}
}
database_helper.dart:
import 'dart:async';
import 'dart:io';
import 'package:path_provider/path_provider.dart';
import 'package:sqflite/sqflite.dart';
import 'package:leisy/model/project.dart';
class DatabaseHelper {
static DatabaseHelper _databaseHelper;
static Database _database;
String projectTable = 'project_table';
String colId = 'id';
String colName = 'name';
String colDate = 'date';
String colLocation = 'location';
String colPersonalDB = 'personalDB';
DatabaseHelper._createInstance();
factory DatabaseHelper() {
if (_databaseHelper == null) {
_databaseHelper = DatabaseHelper._createInstance();
}
return _databaseHelper;
}
Future<Database> get database async {
if (_database == null) {
_database = await initDB();
}
return _database;
}
Future<Database> initDB() async {
Directory directory = await getApplicationDocumentsDirectory();
String path = directory.path + 'projects.db';
var projectsDB = await openDatabase(path, version: 1, onCreate: _createDB);
return projectsDB;
}
void _createDB(Database db, int newVersion) async {
await db.execute('CREATE TABLE $projectTable('
'$colId INTEGER PRIMARY KEY AUTOINCREMENT,'
'$colName TEXT,'
'$colDate TEXT,'
'$colLocation TEXT,'
'$colPersonalDB TEXT)');
}
Future<List<Map<String, dynamic>>> getProjectMapList() async {
Database db = await this.database;
var result = await db.query(projectTable);
return result;
}
Future<int> insertProject(Project project) async {
Database db = await this.database;
var result = await db.insert(projectTable, project.toMap());
return result;
}
Future<int> updateProject(Project project) async {
var db = await this.database;
var result = await db.update(projectTable, project.toMap(), where: '$colId = ?', whereArgs: [project.id]);
return result;
}
Future<int> deleteProject(int id) async {
var db = await this.database;
int result = await db.delete(projectTable, where: '$colId = $id');
return result;
}
Future<int> getCount() async {
Database db = await this.database;
List<Map<String, dynamic>> x = await db.rawQuery('SELECT COUNT (*) from $projectTable');
int result = Sqflite.firstIntValue(x);
return result;
}
Future<List<Project>> getProjectList() async {
var projectMapList = await getProjectMapList();
int count = projectMapList.length;
List<Project> projectList = <Project>[];
for (int i = 0; i < count; i++) {
projectList.add(Project.fromMapObject(projectMapList[i]));
}
return projectList;
}
}
错误:
======== Exception caught by widgets library =======================================================
The following NoSuchMethodError was thrown building NewProjectScreen(dirty, state: _NewProjectScreenState#670bc):
The getter 'name' was called on null.
Receiver: null
Tried calling: name
The relevant error-causing widget was:
NewProjectScreen file:///C:/Users/gabri/AndroidStudioProjects/leisy/lib/surface/main_screen.dart:116:89
When the exception was thrown, this was the stack:
#0 Object.noSuchMethod (dart:core-patch/object_patch.dart:54:5)
#1 _NewProjectScreenState.build (package:leisy/surface/new_project_screen.dart:24:35)
#2 StatefulElement.build (package:flutter/src/widgets/framework.dart:4612:27)
#3 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:4495:15)
#4 StatefulElement.performRebuild (package:flutter/src/widgets/framework.dart:4667:11)
...
====================================================================================================
如果有人能帮助我,我将不胜感激。如果我的代码中有任何不方便或实施不当的地方,请善待我,我是这方面的初学者。
答案 0 :(得分:0)
文件new_project_screen.dart有问题
确切地说,问题可以在行24:35
而且这个项目变量似乎是 null project.name;
那是因为您正在创建 Project 项目但尚未实例化。只是一个空变量
看下面的图片,会帮助你理解一点:
https://dartpad.dev/1ebc897cd3f547cc0b79e52290a63653
所以要修复它,您需要事先创建实例