如何从 Flutter 中的 ListView 中删除项目

问题描述 投票:0回答:1

我正在寻找一种从 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);
                              },
                            ),
                          ],
                        ),
                      ),
                    ],
                  ),
                ),
              ],
            ),
          ),
        );
      },
    );
  }
android flutter listview
1个回答
0
投票

这可以通过多种方式实现。

  1. 等待该项目成功从数据库中删除,然后更新应用程序。这将使用加载器等待数据库事务并使用 setState 在完成后更新 UI。

  2. 通过获取列表项的索引并通过更新应用程序的状态来删除它。

    entireList.removeAt(itemIndex);

我建议你使用方法1。因为你只需使用

Future
.then()

就可以判断数据库中是否出现问题
© www.soinside.com 2019 - 2024. All rights reserved.