从中删除小部件时如何更新ListView?

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

[我是Flutter的初学者,我正在尝试在PositionWidget小部件内创建自定义Card小部件Favorite的列表。非常卡的信息通过api获取。我在列表的每个PositionWidget上添加了一个删除按钮,以从列表中删除此窗口小部件,但是当按下删除按钮并将元素从List<String> favorites中删除时,我不知道如何刷新列表。有人知道吗怎么做或可以链接一些资源来学习呢?谢谢!

class Favourites extends StatefulWidget {
  @override
  _FavouritesState createState() => _FavouritesState();
}

class _FavouritesState extends State<Favourites> {

  List<String> favourites = List<String>();
  final dio = new Dio();

  Future<List<String>> getData() async {
    favourites=MySharedPreferences().favoritePositions;
    List<String> dates = List<String>();
    for (var i=0; i < favourites.length; i++) {
      Response response = await dio.get('http://...api');
      dates.add(response.data['data']);
    }
    return dates;
  }
  Widget getFavourites() {
    return FutureBuilder(
        future: getData(),
        builder: (context, snapshot) {
          if (snapshot.hasData) {
            if (snapshot.data.length > 0) {
              return ListView.builder(
                  itemCount: snapshot.data.length,
                  itemBuilder: (context, index) {
                    return Container(
                      padding: EdgeInsets.fromLTRB(10, 10, 10, 5),
                      height: 140,
                      width: double.maxFinite,
                        child: PositionWidget(key: new Key(index.toString()), streetName: favourites[index], date: snapshot.data[index])
                    );
                  }
              );
            } 
          }
        }
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: getFavourites(),
    );
  }
}

class PositionWidget extends StatefulWidget {
   final String streetName;
   String date;
   PositionWidget({Key key, this.streetName, this.date}) : super(key: key); 

  @override
  _PositionWidgetState createState() => _PositionWidgetState();

  ....
}


listview flutter refresh
1个回答
1
投票

所以您有一个StatefulWidget-让我们利用它。由于没有有效的示例,我无法检查一些代码,而且我不在办公桌旁。但要旨是:

  1. 创建一个存储api调用结果的局部变量
  2. 使用SetState对其进行更新,以使UI知道其已更新
  3. 更改ListView,使其使用此新变量(_dates)
  4. 设置主体检查是否设置了变量,未设置时显示加载指示器
  5. 在PositionWidget上创建可以在父控件上使用的voidcallback
  6. 让父窗口小部件调用void函数删除将在setstate时指定的索引处删除项目,以便ui知道。

我真的希望这段代码是正确的,如果不正确,请告诉我,我可以尝试提供帮助:)-自从我使用setState与API进行交互以来已经有一段时间了,所以我在这里可能做错了什么-我通常使用BLOC管理状态,因此,如果您需要更多帮助,请告诉我。这是示例代码:

class Favourites extends StatefulWidget {
  @override
  _FavouritesState createState() => _FavouritesState();
}

class _FavouritesState extends State<Favourites> {
  List<String> _dates;

  List<String> favourites = List<String>();
  final dio = new Dio();

  Future<List<String>> getData() async {
    favourites=MySharedPreferences().favoritePositions;
    List<String> dates = List<String>();
    for (var i=0; i < favourites.length; i++) {
      Response response = await dio.get('http://...api');
      dates.add(response.data['data']);
    }
    return dates;
  }

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

    getData().then((dates) {
      if(mounted) setState(() => _dates = dates);
    })//You should catch error here too....
  }

  void _deleteItem(int index) {
    if(mounted) setState(() {
      _dates.removeAt(index);
      //I assume you want to remove favorites as well otherwise the two indeces will go out of sync? Maybe?
      //favourites.removeAt(index)
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: _dates == null ?
      Center(child: CircularProgressIndicator()) :
      ListView.builder(
        itemCount: _dates.length,
        itemBuilder: (context, index) {
          return Container(
            padding: EdgeInsets.fromLTRB(10, 10, 10, 5),
            height: 140,
            width: double.maxFinite,
              child: PositionWidget(key: new Key(index.toString()), streetName: favourites[index], date: _dates.data[index], onDelete: () => _deleteItem(index))
          );
        },
      );
    );
  }
}

class PositionWidget extends StatefulWidget {
   final String streetName;
   String date;
   final VoidCallBack onDelete;
   PositionWidget({Key key, this.streetName, this.date, @required this.onDelete}) : super(key: key); 

  @override
  _PositionWidgetState createState() => _PositionWidgetState();

  ///Wherever you have a button or gesture detector or whatever you can click/tap you can call widget.onDelete():
  ///For eg, onTap: () => widget.onDelete()
  ....
}
© www.soinside.com 2019 - 2024. All rights reserved.