从中删除小部件时如何更新 ListView?
How to update ListView when deleting a widget from it?
我是 Flutter 的初级开发人员,我正在尝试在 Favorite
小部件中创建自定义 Card 小部件列表 PositionWidget
。非常卡的信息打通api。我在列表的每个 PositionWidget 上添加了一个删除按钮,以从列表中删除此小部件,但我不知道如何在按下删除按钮并从 List<String> favorites
中删除元素时刷新列表。任何人都知道如何做到这一点,或者可以 link 一些资源来学习这个?谢谢!
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();
....
}
所以你有一个 StatefulWidget
- 让我们好好利用它。我无法检查我的一些代码,因为我没有工作样本,而且我不在办公桌前。但要点是:
- 创建一个局部变量来存储 api 调用的结果
- 使用 SetState 更新它,以便 UI 知道它已被更新
- 更改 ListView 以便它使用这个新变量 (_dates)
- 设置主体检查变量是否已设置,未设置时显示加载指示器
- 在 PositionWidget 上创建一个可以在父 widget 上使用的 voidcallback
- 让父窗口小部件调用一个 void 函数,该函数删除在设置状态时指定的索引处的项目,以便 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()
....
}
我是 Flutter 的初级开发人员,我正在尝试在 Favorite
小部件中创建自定义 Card 小部件列表 PositionWidget
。非常卡的信息打通api。我在列表的每个 PositionWidget 上添加了一个删除按钮,以从列表中删除此小部件,但我不知道如何在按下删除按钮并从 List<String> favorites
中删除元素时刷新列表。任何人都知道如何做到这一点,或者可以 link 一些资源来学习这个?谢谢!
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();
....
}
所以你有一个 StatefulWidget
- 让我们好好利用它。我无法检查我的一些代码,因为我没有工作样本,而且我不在办公桌前。但要点是:
- 创建一个局部变量来存储 api 调用的结果
- 使用 SetState 更新它,以便 UI 知道它已被更新
- 更改 ListView 以便它使用这个新变量 (_dates)
- 设置主体检查变量是否已设置,未设置时显示加载指示器
- 在 PositionWidget 上创建一个可以在父 widget 上使用的 voidcallback
- 让父窗口小部件调用一个 void 函数,该函数删除在设置状态时指定的索引处的项目,以便 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()
....
}