我正在寻找一种从 ListView.builder 外部删除 ListView 项目的方法。 项目名称和索引已知。我希望通过 ListView.removeAt(itemIndex); 来实现这一点,但不幸的是这不起作用。
一般来说...有两个FloatingActionButton:fab1 和fab2。一旦 fab2 被按下,removeItem(itemName) 函数就会被调用,以便从数据库中删除数据(这可以正常工作),一旦数据被删除,项目应该从 ListView 中删除(这不起作用,因为我不知道如何引用 ListView) .
您能否建议在这种情况下如何从 ListView 中删除项目?
完整代码附在下面:
Future<List<PostListDetails>> postsFuture = getPosts();
bool showButton = false;
String itemName ="";
int itemIndex = 0;
static Future<List<PostListDetails>> getPosts() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
final token = await prefs.getString('token');
final listID = await prefs.getString('listID');
final lista = await prefs.getString('lista');
Response response = await post(Uri.parse('someURL'),
headers: <String, String>{
'Accept': 'application/json',
'Authorization': 'Bearer $token',
},
body: <String, String>{
'listID': '$listID',
},
);
if(response.statusCode != 200){
print('Błąd połączenia z bazą danych... status[${response.statusCode}]');
}
final List body = json.decode(response.body);
return body.map((e) => PostListDetails.fromJson(e)).toList();
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.grey[100],
floatingActionButton: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
FloatingActionButton.extended(
heroTag: "fab1",
onPressed: () {
print('---> addList()');
// addList();
},
icon: const Icon(Icons.add_circle_outline),
label: const Text('Dodaj'),
),
if (showButton)
FloatingActionButton.extended(
heroTag: "fab2",
onPressed: () {
print('---> removing $itemName');
removeItem(itemName); // this function removes data from database
//ListView.removeAt(itemIndex); <--- I do not know how to do this
setState(() => showButton = false);
},
icon: const Icon(Icons.delete),
label: const Text('Usuń'),
),
],
),
appBar: AppBar(
backgroundColor: Colors.grey[900],
title: const Text('Lista zakupowa'),
actions: [
IconButton(
onPressed: signUserOut,
icon: const Icon(Icons.logout),
),
],
),
body: Center(
child: FutureBuilder<List<PostListDetails>>(
future: postsFuture,
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return const CircularProgressIndicator();
} else if (snapshot.hasData) {
return buildPosts(snapshot.data!);
} else {
return const Text("Brak danych...");
}
},
),
),
);
}
@override
Widget buildPosts(List<PostListDetails> posts) {
return ListView.builder(
itemCount: posts.length,
itemBuilder: (context, index) {
final post = posts[index];
int customCompare(PostListDetails a, PostListDetails b) {
if (a.status != b.status) {
return a.status!.toInt() - b.status!.toInt();
}
final int categoryCompare = a.kategoria.toString().compareTo(b.kategoria.toString());
if (categoryCompare != 0) {
return categoryCompare;
}
return a.nazwa.toString().compareTo(b.nazwa.toString());
}
return GestureDetector(
onLongPress: () {
itemName = post.nazwa!;
itemIndex = index;
setState(() => showButton = true);
},
child: Container(
color: post.status! % 2 == 1 ? Colors.grey[100] : Colors.white,
margin: const EdgeInsets.symmetric(vertical: 0.5, horizontal: 0),
padding: const EdgeInsets.symmetric(vertical: 5, horizontal: 15),
height: 50,
width: double.maxFinite,
child: Row(
children: [
Expanded(
flex: 8,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
post.nazwa!,
textAlign: TextAlign.left,
style: const TextStyle(fontWeight: FontWeight.bold, fontSize: 15, color: Colors.black),
),
Text(
'${post.waga!.toString()} g.',
textAlign: TextAlign.left,
style: const TextStyle(fontWeight: FontWeight.normal, fontSize: 15, color: Colors.grey),
),
],
),
),
Expanded(
flex: 2,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Expanded(
flex: 0,
child: Row(),
),
Expanded(
flex: 10,
child: Row(
children: [
CatIcon(imagePath: (Cat2Ico(post.kategoria!.toString()))),
Checkbox(
value: Int2Bool(post.status!.toInt()),
onChanged: (value) {
setState(() {
post.status = Bool2Int(value!);
});
saveStatus(post.nazwa!, post.status!, index);
posts.sort(customCompare);
},
),
],
),
),
],
),
),
],
),
),
);
},
);
}
这可以通过多种方式实现。
等待该项目成功从数据库中删除,然后更新应用程序。这将使用加载器等待数据库事务并使用 setState 在完成后更新 UI。
通过获取列表项的索引并通过更新应用程序的状态来删除它。
entireList.removeAt(itemIndex);
我建议你使用方法1。因为你只需使用
Future
和 .then()
就可以判断数据库中是否出现问题