我已经创建了一个详细信息页面,并使用了Medium文章中的示例。我能够成功执行CRUD操作。
当我加载DetailsPage时,我想检查表是否具有ID,如果是,则将收藏夹图标设为黄色。
class _DetailPageState extends State<DetailPage> {
bool isFav = false;
MyImpData myData;
_DetailPageState(this.myData);
// reference to our single class that manages the database
final dbHelper = DatabaseHelper.instance;
@override
Widget build(BuildContext context) {
Widget heading = new Container(...),);
Widget middleSection = new Expanded(...);
Widget bottomBanner = new Container(...),);
Widget body = new Column(...);
final makeBottom = Container(
height: 55.0,
child: BottomAppBar(
color: Color.fromRGBO(58, 66, 86, 1.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
IconButton(
icon: buildIcon(),
onPressed: () {
_insertOrDelete(myData.id);
},
),
IconButton(
icon: Icon(Icons.share, color: Colors.white),
onPressed: () => share(context, myData),
)
],
),
),
);
return Scaffold(
appBar: AppBar(...),
body: Container(...),
bottomNavigationBar: makeBottom,
);
}
Icon buildIcon() {
if (isFav) {
return Icon(Icons.favorite, color: Colors.yellow);
} else {
return Icon(Icons.favorite_border, color: Colors.white);
}
}
void share(BuildContext context, MyImpData myData) {...}
void _insert() async {
// row to insert
Map<String, dynamic> row = {
DatabaseHelper.columnName: myData.name,
DatabaseHelper.columnDesc: myData.desc,
DatabaseHelper.columnLoc: myData.location,
DatabaseHelper.columnId: myData.id
};
final id = await dbHelper.insert(row);
print('inserted row id: $id');
}
void _checkFav(String checkId) async {
final rowsPresent = await dbHelper.queryForFav(checkId);
if (rowsPresent > 0) {
print('success');
isFav = true;
} else {
print('Nothing found so inserting you dodo');
isFav = false;
//_insert();
}
//rowsPresent.forEach((row) => print(row));
}
void _insertOrDelete(String id) async {
final rowsPresent = await dbHelper.queryForFav(id);
if (rowsPresent > 0) {
print('Its favourite and removing it');
_delete();
isFav = false;
} else {
print('Nothing found so inserting you dodo');
_insert();
isFav = true;
}
}
void _delete() async {...}
}
DBHelper.dart文件的queryForFav(id)具有以下内容
//Raw query to check if it is in the favourites
Future<int> queryForFav(String checkId) async {
Database db = await instance.database;
int noOfRows = 0;
try {
noOfRows = Sqflite.firstIntValue(await db.rawQuery(
'SELECT COUNT(*) FROM $table WHERE $columnId = ?',
['$checkId']));
} catch (e) {
print(e);
}
return noOfRows;
}
我的尝试是创建一个标志isFav并在检查数据库时进行设置。但是,这总是错误的,因为没有执行查询。只有当我按下按钮时,才会执行实际的数据库查询。 任何帮助,将不胜感激。
答案 0 :(得分:0)
更改此类的IconButton(child,buildIcon(),...)
class FavIconWidget extends StatefulWidget {
final MyImpData myData;
FavIconWidget(this.myData);
@override
_FavIconWidgetState createState() => _FavIconWidgetState();
}
class _FavIconWidgetState extends State<FavIconWidget> {
final dbHelper = DatabaseHelper.instance;
Future<bool> get isFav async {
final rowsPresent = await dbHelper.queryForFav(widget.myData.id);
if (rowsPresent > 0) {
print('Its favourite and removing it');
await _delete();
return false;
} else {
print('Nothing found so inserting you dodo');
await _insert();
return true;
}
}
void _insert() async {
// row to insert
Map<String, dynamic> row = {
DatabaseHelper.columnName: widget.myData.name,
DatabaseHelper.columnDesc: widget.myData.desc,
DatabaseHelper.columnLoc: widget.myData.location,
DatabaseHelper.columnId: widget.myData.id
};
final id = await dbHelper.insert(row);
print('inserted row id: $id');
}
void _delete() async {}
@override
Widget build(BuildContext context) {
return FutureBuilder<bool>(
future: isFav,
initialData: false,// you can define an initial value while the db returns the real value
builder: (context, snapshot) {
if(snapshot.hasError) return const Icon(Icons.error, color: Colors.red); //just in case the db return an error
return IconButton(
icon: snapshot.data ? const Icon(Icons.favorite, color: Colors.yellow) :
Icon(Icons.favorite, color: Colors.white),
onPressed: () => setState(() {})
);
});
}
}
基本上,它用FutureBuilder包装图标,这是一个特殊的小部件,等待一个未来值(在这种情况下,返回数据库行),您可以在等待时为其提供初始值(在这种情况下,我给它一个false),但您可以忽略它,并使用snapshot.hasData检查是否有一个值,然后返回CircularProgressIndicator来告诉用户您正在获取数据
return FutureBuilder<bool>(
future: isFav,
initialData: false,// you can define an initial value while the db returns the real value
builder: (context, snapshot) {
if(snapshot.hasError) return const Icon(Icons.error, color: Colors.red); //just in case the db return an error
if(snapshot.hasData)
return IconButton(
icon: snapshot.data ? const Icon(Icons.favorite, color: Colors.yellow) :
Icon(Icons.favorite, color: Colors.white),
onPressed: () => setState(() {})
);
return CircularProgressIndicator(); //if there is no initial value and the future is not yet complete
});
我制作了这个StatefulWidget,所以当您按下按钮setState并重新运行isFav future来再次检查数据库时(但它只是重新构建了此iconbutton,而不是整个页面)。如果您要根据isFav值而不是仅根据图标来更新整个页面,则必须在该Scaffold的正文中或至少在您确实需要检查该值的小部件树中使用该FutureBuilder。