删除项目后刷新列表 - 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的主要内容,如果未能解决你的问题,请参考以下文章