【发布时间】:2021-10-01 17:42:20
【问题描述】:
我正在从 sqflite 数据库中查询数据并使用 futurebuilder 来显示刷新图标。一旦通过 snapshot.connectionState == ConnectionState.done 检索到数据,我将调用 ListView.builder 方法来显示数据。我在显示的每个列表项中也有一个图标。单击该项目后,我将切换数据库中的列值。因为我还需要在每次点击时切换 ui 中的图标。为此,在更新数据库后,我调用了 setstate。这会切换 ui 中的图标,但由于 setstate,整个项目列表正在重建。我怎样才能避免这种情况?我只想改变那个特定列表项的图标。 Provider 是实现这一目标的推荐方法吗?
class _HomeState extends State<Home> {
final _dbHelper = DatabaseHelper.instance;
Future<int> _toggleFavourite(int id, int value) async {
return await _dbHelper.updateFavourite(id, value);- //toogles the column value in db
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: FutureBuilder(
future: _dbHelper.queryAllRows(),//Get all rows from db
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
final _allRows = snapshot.data as List<Map<String, dynamic>>;
_codes.clear();
_allRows.forEach((row) => _codes.add(Code.fromMap(row)));
return SafeArea(
child: Column(
children: [
Expanded(
child:ListView.builder(
padding: const EdgeInsets.all(8),
itemCount: _codes.length,
itemBuilder:
(BuildContext context, int index) {
return InkWell(
onTap: () {
},
child: Card(
child: ListTile(
title: Text(
_codes[index].code,
maxLines: 1,
overflow: TextOverflow.ellipsis,
softWrap: false,
),
trailing: SizedBox(
width: 100,
child: Row(
children: [
IconButton(
onPressed: () {
_toggleFavourite(
_codes[index]
.id,
_codes[index]
.favourite ==
1
? 0
: 1)
.then(
(affectedRows) {
if (affectedRows >
0) {
setState(() {});//Rebuilds all the listitems :(
}
});
},
icon: Icon(
_codes[index]
.favourite ==
1
? Icons.favorite
: Icons
.favorite_border_outlined,
size: 35,
)),
.........
【问题讨论】:
-
如果你想阻止任何东西重建,你应该使用'const'关键字。但是,如果您共享代码会更好。
-
我怀疑更新唯一的图标是可能的!如果它正在重建完整列表,你会感到困扰吗?
标签: flutter