我正在尝试使用从 Sqflite 数据库中获取的帐户信息填充 ListView。这是我从 db 读取帐户数据的方式:
dbhelper.dart
Future<List<AccountModel>> getAllAccounts() async {
final dbClient = await db;
print('getAllAccounts');
List<Map> res = await dbClient.rawQuery('SELECT * FROM Accounts');
if (res.isNotEmpty) {
print('Accounts $res');
var accounts = [];
for (var i = 0; i < res.length; i++) {
var account =AccountModel.fromDb(res[i]);
print('Account $account');
accounts.add(account);
}
print('Return $accounts');
return accounts;
}
return [];
这就是我如何尝试使用FutureBuilder -Widget 构建列表视图:
account_list_widget.dart
class AccountList extends StatefulWidget {
State<StatefulWidget> createState() {
return AccountListState();
}
}
class AccountListState extends State<AccountList> {
@override
Widget build(BuildContext context) {
return Stack(
children: <Widget>[
FutureBuilder<List<AccountModel>>(
future: DbProvider().getAllAccounts(),
builder: (BuildContext context, AsyncSnapshot<List<AccountModel>> snapshot) {
if (snapshot.hasData) {
return Stack(
children: <Widget>[
ListView.builder(
itemCount: snapshot.data.length + 1,
itemBuilder: (BuildContext context, int index) {
if (index == 0) {
return ListSectionHeader('Konten');
} else {
// Korrigieren des Index, da ja die 0 schon "verbraucht" wurde,
// auf die Daten aber weiterhhin mit Start-Index 0 zugegriffen wird.
index--;
AccountModel account = snapshot.data[index];
return Dismissible(
key: UniqueKey(),
background: Container(color: Colors.red),
onDismissed: (direction) {
DbProvider().removeAccount(account.uuid);
},
child: ListTile(
title: Text(account.accountName),
leading: Icon(Icons.crop_square),
trailing: Icon(Icons.keyboard_arrow_right),
),
);
}
},
),
addAccountTile()
],
);
} else {
return ListView.builder(
itemCount: 2,
itemBuilder: (BuildContext context, int index) {
if (index == 0) {
return ListSectionHeader('Konten2');
} else {
return addAccountTile();
}
},
);
}
},
),
],
);
}
Widget addAccountTile() {
return ListTile(
title: Text('Neues Konto hinzufügen'),
leading: Icon(
Icons.add_circle,
color: Colors.blue,
),
trailing: Icon(Icons.keyboard_arrow_right),
onTap: () {
Navigator.pushNamed(context, '/newaccount');
}
);
}
}
自定义数据模型定义如下:
account_model.dart
class AccountModel {
final String uuid;
final String accountName;
final String host;
final String userName;
final String password;
final String lastConnected;
final bool active;
final bool useHeadset;
AccountModel(this.uuid, this.accountName, this.host, this.userName,
this.password, this.lastConnected, this.active, this.useHeadset);
AccountModel.fromJson(Map<String, dynamic> parsedJson)
: uuid = parsedJson['uuid'],
accountName = parsedJson['accountName'],
host = parsedJson['host'],
userName = parsedJson['userName'],
password = parsedJson['password'],
lastConnected = parsedJson['lastConnected'],
active = parsedJson['active'],
useHeadset = parsedJson['useHeadset'];
AccountModel.fromDb(Map<String, dynamic> parsedJson)
: uuid = parsedJson['uuid'],
accountName = parsedJson['accountName'],
host = parsedJson['host'],
userName = parsedJson['userName'],
password = parsedJson['password'],
lastConnected = parsedJson['lastConnected'],
active = parsedJson['active'] == 1,
useHeadset = parsedJson['useHeadset'] == 1;
Map<String, dynamic> toMap() {
return <String, dynamic> {
'uuid': uuid,
'accountName': accountName,
'host': host,
'userName': userName,
'password': password,
'lastConnected': lastConnected,
'active': active ? 1 : 0,
'useHeadset': useHeadset ? 1 : 0
};
}
}
我的问题是,尽管数据库存储了有效数据,而且该方法getAllAccounts()
似乎返回了有效数据,snapshot.hasdata
但 FutureBuilder 小部件中的语句始终为false。
这里出了什么问题?
从控制台:
D/Sqflite ( 9179): [Thread[main,5,main]] opened 6 /data/user/0/com.example.dashboard/app_flutter/test.db total open count (6)
D/Sqflite ( 9179): [Thread[Sqflite,5,main]] BEGIN EXCLUSIVE
D/Sqflite ( 9179): [Thread[Sqflite,5,main]] PRAGMA user_version;
D/Sqflite ( 9179): [Thread[Sqflite,5,main]] PRAGMA user_version = 1;
D/Sqflite ( 9179): [Thread[Sqflite,5,main]] COMMIT
I/flutter ( 9179): getAllAccounts
D/Sqflite ( 9179): [Thread[Sqflite,5,main]] SELECT * FROM Accounts
I/flutter ( 9179): Accounts [{uuid: 436f2c10-3260-11e9-fe03-65fdfe3a7bbd, accountName: 12345, host: 12345, userName: 12345, password: 12345, lastConnected: 0, active: 0, useHeadset: 0}]
I/flutter ( 9179): Account Instance of 'AccountModel'
I/flutter ( 9179): Return [Instance of 'AccountModel']
(控制台中此代码段的最后一行对应于“getAllAccounts”方法末尾的打印语句。)