【问题标题】:Refresh list after deleting an item - Flutter删除项目后刷新列表 - 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() 。 (当然是在删除之后)
  • 我做到了。但它没有刷新列表

标签: list api flutter


【解决方案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)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-12-21
        • 2021-09-02
        • 1970-01-01
        • 2023-01-25
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多