flutter - 假设一个列表被分配了一个 SQLite 数据库的查询,如何确保该列表不为空?扑
问题描述
我正在使用 sqflite 包制作一个带有 SQLite 数据库的 Flutter 应用程序。我有一个带有必要方法的数据库助手类。在其中一个页面中,我想将数据显示为卡片列表。我也有一个图像存储到数据库中,因此在同一页面中我必须将图像转换回文件。在那个名为 DataPage 的页面类中,我创建了一个名为 query 的方法,它调用数据库的 query 方法并将该值分配给一个名为 listLokasi 的列表。我还创建了一个名为 convert 的方法,它调用 List.generate,其中一个参数是 listLokasi.length。同时,我将这 2 个方法放在 _DataPageState 的构造函数中,因为 DataPage 是一个有状态的小部件。问题是当我运行应用程序时,当我尝试在 null 上调用 length 时显示一个错误,显示 NoSuchMethodError,这意味着 listLokasi 为空。所以我在查询方法中,在查询方法之后的构造函数中,在转换方法中都放置了断言。结果是查询方法中的断言没有触发,而构造函数中的断言立即触发。我检查了我的数据库助手类并查看了我的代码,但我找不到我的代码中的缺陷。对此问题的任何帮助将不胜感激。我将在下面显示代码。
这是数据库助手类。
class DatabaseHelper {
static final _instance = DatabaseHelper._internal();
DatabaseHelper._internal();
factory DatabaseHelper() {
return _instance;
}
Database db;
Future initDatabase() async {
var databasePath = await getDatabasesPath();
var path = join(databasePath, 'table.db');
db = await openDatabase(path, version: 1, onCreate: onCreate);
}
onCreate(Database db, int version) async {
await db.execute('''
CREATE TABLE lokasi
(id INTEGER PRIMARY KEY,
name TEXT,
description TEXT,
category TEXT,
latitude REAL,
longitude REAL,
image BLOB)
''');
}
Future<Lokasi> insert(Lokasi lokasi) async {
await db.insert('lokasi', lokasi.toJson());
return lokasi;
}
Future<List<Lokasi>> query() async {
var list = await db.query('lokasi');
return List.generate(list.length, (i) => Lokasi.fromJson(list[i]));
}
}
这是 DataPage 类。
class DataPage extends StatefulWidget {
final savedUsername;
const DataPage({this.savedUsername = 'User'});
@override
_DataPageState createState() => _DataPageState();
}
class _DataPageState extends State<DataPage> {
DatabaseHelper db = DatabaseHelper();
List<Lokasi> listLokasi;
List<LokasiConvert> listLokasiConvert;
_DataPageState() {
query();
assert(listLokasi != null);
convert();
}
convert() {
assert(listLokasi != null);
listLokasiConvert = List.generate(
listLokasi.length,
(i) => LokasiConvert(
name: listLokasi[i].name,
description: listLokasi[i].category,
category: listLokasi[i].category,
latitude: listLokasi[i].latitude,
longitude: listLokasi[i].longitude,
image: File.fromRawPath(listLokasi[i].image),
),
);
}
Future<List<Lokasi>> query() async {
listLokasi = await db.query();
assert(listLokasi != null);
return listLokasi;
}
void sendUsername(BuildContext context) {
String username = widget.savedUsername;
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => MainPage(username: username),
),
);
}
void sendUsernameToChart(BuildContext context) {
String chartUsername = widget.savedUsername;
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => ChartPage(savedUsername: chartUsername),
),
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
automaticallyImplyLeading: false,
title: Text('Data'),
actions: [
RaisedButton(
child: Text('Logout'),
onPressed: () {
Navigator.popUntil(context, ModalRoute.withName('/'));
},
),
RaisedButton(
child: Text('Main'),
onPressed: () {
sendUsername(context);
},
),
RaisedButton(
child: Text('Charts'),
onPressed: () {
sendUsernameToChart(context);
},
),
],
),
body: ListView.builder(
itemBuilder: (context, i) {
return Card(
child: Row(
children: [
Image.file(
listLokasiConvert[i].image,
width: 100,
height: 100,
),
Column(
children: [
Text(listLokasiConvert[i].name),
Text(listLokasiConvert[i].category),
Text(listLokasiConvert[i].description),
Text('Coordinates: ' +
listLokasiConvert[i].latitude.toString() +
', ' +
listLokasiConvert[i].longitude.toString()),
],
)
],
));
},
itemCount: listLokasiConvert.length,
),
);
}
}
再次感谢您提供的任何帮助。
解决方案
也许你可以试试这个。希望对您有所帮助。
db.query().then((value) {
setState(() {
listLokasi = value
});
});
推荐阅读
- python - 字符串没有属性 .loc
- javascript - How do I break up a JSON object to insert into a MySQL table?
- mysql - 如何查询表A中的特定数据,然后将A中的字段与表B中的字段进行比较?
- reactjs - React Custom Hook set 返回的函数不是函数
- web - 为什么特定 URL 网址存在但其父文件夹不存在
- generics - 复制 Kotlin 数组减去特定索引处的元素
- opengl - mod 函数是否在 OpenGL 3.3 核心中返回 highp 浮点数?
- python - 消息的未知 id
- linux - 在 bash 中进行字符串替换时出错
- python - Python 在另一个语句中传递语句的输出以进行评估