删除项目后刷新列表 - Flutter

Posted

技术标签:

【中文标题】删除项目后刷新列表 - Flutter【英文标题】:Refresh list after deleting an item - Flutter 【发布时间】:2019-08-16 11:08:22 【问题描述】:

我试图让列表在按下弹出菜单上的删除选项后自动刷新。它将删除选定的 从 api 调用的项目列表中的项目。该项目应在按下删除后立即消失。

用 api 数据填充列表的 API 调用:

  List data;

  @override
  void initState() 
    super.initState();
    this.getJsonData();
  

  Future<String> getJsonData() async 
    var response = await http.get(
      Uri.encodeFull(url),
      headers: "Accept": "application/json",
    );

    var extractdata = json.decode(response.body);
    data = extractdata['levels'];
    levelsData = data;

    setState(
      () 
        var extractdata = json.decode(response.body);
        data = extractdata['levels'];
      ,
    );
    return "Success";
  

...

删除的API调用:

  delete() async 
    String url = "http://31.183.125.253:8080/users";

    Map map = 
      'price': 1.23,
      'user_id': 'user2'
    ;

    print(await apiRequest(url, map));
  

  Future<String> apiRequest(String url, Map jsonMap) async 
    HttpClient httpClient = new HttpClient();
    HttpClientRequest request = await httpClient.deleteUrl(Uri.parse(url));
    request.headers.set('content-type', 'application/json');
    request.add(utf8.encode(json.encode(jsonMap)));
    HttpClientResponse response = await request.close();
    String statusCode = response.statusCode.toString();
    String reply = await response.transform(utf8.decoder).join();

    print(statusCode);

    httpClient.close();
    return reply;
  

存储来自 api 调用的列表的扩展磁贴:

...

var levelsData = [];

  @override
  Widget build(BuildContext context) 
    List<dynamic> _getChildren() 
      List<Widget> children = [];
      levelsData.forEach(
        (element) 
            children.add(
              ListTile(
                title: Text(element['price'].toString(),
                trailing: PopUpMenu(
                  onDelete: () 
                    setState(() 
                      delete();
                    );
                  ))
            );
      );
      return children;
    
  

...

弹出菜单:

class PopUpMenu extends StatelessWidget 
  VoidCallback onDelete;

  PopUpMenu(this.onDelete);

  void showMenuSelection(String value) 
    switch (value) 
      case 'Delete':
        onDelete();
        break;
      // Other cases for other menu options
    
  

我可以删除选择要删除的项目,但该项目没有从列表中消失,也没有显示列表的更改。

【问题讨论】:

你在哪里设置levelsData 它在我调用的另一个类中。更新了上面的代码 按下按钮时只需调用 setState() 。 (当然是在删除之后) 我做到了。但它没有刷新列表 【参考方案1】:

Flutter 应该自动更新以反映对数据源的更改。但是,这仅在调用后应用:

setState(()

);

所以应该在您从列表中删除项目后运行。

【讨论】:

【参考方案2】:

您必须调用 setState 并从列表中删除该项目。

     class _MyListViewState extends State<MyListView> 
          MyDB _myDB;
          List<MyItem> _myList;

        ...

      void getData() async 
        ...

        _myDB.getData().then((items) 
          setState(() 
            _myList = items;
          );
        );
      

      @override
      void initState() 
        super.initState();
        getData();
      

              @override
              Widget build(BuildContext context) 
                return (_myList== null || _myList.isEmpty)
                    ? Center(child: Text('Nothing to see...'))
                    : ListView.builder(
                        itemCount: _myList.length,
                        itemBuilder: (context, index) 
                          return

        ... onPress ...

                _myDB.deleteItem(_myList[index]).whenComplete(() 
                                                setState(() 
                                                  _myList.removeAt(index);
                                                );
                                              );

【讨论】:

【参考方案3】:

从列表视图的顶部和中间删除项目时遇到问题 索引不在正确的范围内 导入“包:颤振/material.dart”; 导入'package:flutter_tindercard/flutter_tindercard.dart';

class ExampleHomePage extends StatefulWidget 
  @override
  _ExampleHomePageState createState() => _ExampleHomePageState();


class _ExampleHomePageState extends State<ExampleHomePage>
    with TickerProviderStateMixin 
  List approved = [];
  List refused = [];

  List<String> welcomeImages = [
    "https://images.unsplash.com/photo-1631636176993-759dea1a1300?ixid=MnwxMjA3fDB8MHxlZGl0b3JpYWwtZmVlZHw0fHx8ZW58MHx8fHw%3D&ixlib=rb-1.2.1&auto=format&fit=crop&w=500&q=60",
    "https://images.unsplash.com/photo-1631634176568-f543af6a41de?ixid=MnwxMjA3fDB8MHxlZGl0b3JpYWwtZmVlZHw3fHx8ZW58MHx8fHw%3D&ixlib=rb-1.2.1&auto=format&fit=crop&w=500&q=60",
    "https://images.unsplash.com/photo-1631691971564-adf9419d904e?ixid=MnwxMjA3fDB8MHxlZGl0b3JpYWwtZmVlZHwxM3x8fGVufDB8fHx8&ixlib=rb-1.2.1&auto=format&fit=crop&w=500&q=60",
    "https://images.unsplash.com/photo-1631641906574-24adb8594649?ixid=MnwxMjA3fDB8MHxlZGl0b3JpYWwtZmVlZHwxMnx8fGVufDB8fHx8&ixlib=rb-1.2.1&auto=format&fit=crop&w=500&q=60",
    "https://images.unsplash.com/photo-1593642702821-c8da6771f0c6?ixid=MnwxMjA3fDF8MHxlZGl0b3JpYWwtZmVlZHwxMXx8fGVufDB8fHx8&ixlib=rb-1.2.1&auto=format&fit=crop&w=500&q=60",
    "https://images.unsplash.com/photo-1631621461675-e61a1f28d3d6?ixid=MnwxMjA3fDB8MHxlZGl0b3JpYWwtZmVlZHw0NHx8fGVufDB8fHx8&ixlib=rb-1.2.1&auto=format&fit=crop&w=500&q=60"
  ];
  List<TinderCarder> cards = [];
  CardController controller = CardController(); //Use this to trigger swap.

  @override
  void initState() 
    // TODO: implement initState
    super.initState();
    for (int i = 0; i < welcomeImages.length; i++) 
      cards.add(TinderCarder(
          controller: controller,
          image: welcomeImages[i],
          onLeftPress: () 
            setState(() 
              print('index is: ' + i.toString());

              cards.removeAt(i);
              print('index is: ' + i.toString());
              print('list length: ' + cards.length.toString());
            );
          ,
          onRightPress: () 
            setState(() 
              print('index is: ' + i.toString());

              cards.removeAt(i);
              print('index is: ' + i.toString());
              print('list length: ' + cards.length.toString());
            );
          ));
    
    // cards = welcomeImages.map((element) 
    //   return TinderCarder(
    //     image: element,
    //     controller: controller,
    //     onLeftPress: () 
    //       setState(() 
    //         cards.removeAt(element.indexOf(element));
    //         print('index is: ' + "$element.indexOf(element)");
    //         print('list length: ' + cards.length.toString());
    //       );
    //     ,
    //     onRightPress: () 
    //       setState(() 
    //         cards.removeAt(element.indexOf(element));
    //         print('index is: ' + "$element.indexOf(element)");
    //         print('list length: ' + cards.length.toString());
    //       );
    //     ,
    //   );
    // ).toList();
  

  @override
  Widget build(BuildContext context) 
    return Scaffold(
      body: Container(
        width: double.infinity,
        child: ListView.builder(
          shrinkWrap: true,
          key: Key(cards.length.toString()),
          physics: ScrollPhysics(),
          itemBuilder: (ctx, index) 
            return cards[index];
          ,
          itemCount: cards.length,
        ),
      ),
    );
  


class TinderCarder extends StatelessWidget 
  final String image;
  Function onLeftPress;
  Function onRightPress;
  var controller;

  TinderCarder(
      required this.image,
      this.controller,
      required this.onLeftPress,
      required this.onRightPress);

  @override
  Widget build(BuildContext context) 
    return Container(
      height: 300,
      child: TinderSwapCard(
        orientation: AmassOrientation.BOTTOM,
        totalNum: 1,
        stackNum: 3,
        swipeEdge: 4.0,
        maxWidth: double.infinity,
        maxHeight: MediaQuery.of(context).size.width * 0.9,
        minWidth: MediaQuery.of(context).size.width * 0.8,
        minHeight: MediaQuery.of(context).size.width * 0.8,
        cardBuilder: (context, index) => Card(
          child: Column(
            children: [
              Image.network(
                image,
                width: double.infinity,
                height: 200,
                fit: BoxFit.cover,
              ),
              Text('Data')
            ],
          ),
        ),
        cardController: controller,
        swipeUpdateCallback: (DragUpdateDetails details, Alignment align) 
          /// Get swiping card's alignment
          if (align.x < 0) 
           else if (align.x > 0) 
        ,
        swipeCompleteCallback: (CardSwipeOrientation orientation, int index) 
          print(orientation.toString());
          if (orientation == CardSwipeOrientation.LEFT) 
            print("Card is LEFT swiping");
            // print(welcomeImages.length);
            onLeftPress();
           else if (orientation == CardSwipeOrientation.RIGHT) 
            print("Card is RIGHT swiping");
            // print(welcomeImages.length);
            onRightPress();
          
        ,
      ),
    );
  

错误

======== 动画库捕获的异常================================== ==================== 通知 AnimationController 的状态侦听器时引发以下 RangeError: RangeError(索引):无效值:不在包含范围 0..3:4

当异常被抛出时,这是堆栈: #0 列表。[] (dart:core-patch/growable_array.dart:254:60) #1 List.removeAt (dart:core-patch/growable_array.dart:23:22) #2 _ExampleHomePageState.initState.. (package:untitled/views/sweep_cards.dart:46:21) #3 State.setState (package:flutter/src/widgets/framework.dart:1088:30) #4 _ExampleHomePageState.initState。 (包:untitled/views/sweep_cards.dart:43:13) ... AnimationController 通知状态监听器是:AnimationController#d4459(⏭ 1.000; paused)

【讨论】:

以上是关于删除项目后刷新列表 - Flutter的主要内容,如果未能解决你的问题,请参考以下文章

XMPP框架下微信项目总结刷新好友列表(删除,添加好友)

刷新后在标签中显示文本

从列表视图中删除一行后刷新片段

vue列表数据删除后的主动刷新页面及刷新方法

CoreData 删除后的列表刷新

通过上下文菜单删除后刷新自定义列表视图