如何在 Flutter 中删除列表视图顶部的项目?
Posted
技术标签:
【中文标题】如何在 Flutter 中删除列表视图顶部的项目?【英文标题】:How to remove item at the top of List View in Flutter? 【发布时间】:2021-07-07 13:07:22 【问题描述】:我有列表视图,并且在列表中的每个项目中都有一个名为“删除项目”的按钮。当我在每个项目中按下该按钮时,我只想从列表中删除该项目。
但它不会删除项目,它只是显示我指定的 Toast 消息。
我该如何解决这个问题?
这是代码:
Widget build(BuildContext context)
listItems = buildVCsFromAPI(context);
return Container(
child: ListView.builder(
itemBuilder: (context, index) =>
_buildListItem(context, listItems[index], index),
itemCount: listItems.length,
physics: AlwaysScrollableScrollPhysics()),
);
Widget _buildListItem(
BuildContext context, _VerifiableCredentialListItem cert, int index)
return GestureDetector(
child: AnimatedAlign(
curve: Curves.ease,
duration: Duration(milliseconds: 500),
heightFactor: selectedPosition == index ? factorMax : factorMin,
alignment: Alignment.topCenter,
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(10)), //here
color: Colors.white,
boxShadow: [
BoxShadow(
color: Colors.grey.withOpacity(0.5),
offset: Offset(0, -1),
blurRadius: 10.0)
]),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
HeadingRow(title: cert.fullTitle, appIcon: cert.appIcon),
displayListItem(index, selectedPosition, cert)
],
),
),
),
Column displayListItem(
int index, int selectedIndex, _VerifiableCredentialListItem cert)
CredentialListGroupType groupType = cert.groupType;
return Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
SizedBox(
height: UIConstants.s2,
),
buildAnotherWidget(),
SizedBox(
height: UIConstants.s3,
),
buildDeleteAndExportButtons(),
],
);
Column buildDeleteAndExportButtons()
return Column(
children: [
Padding(
padding: EdgeInsets.symmetric(
vertical: UIConstants.s1, horizontal: UIConstants.s2),
child: Row(
children: [
Expanded(
flex: 1,
child: BlueButtonWithIcon(
text: 'Delete item',
icon: 'assets/icons/delete-icon.svg',
onPressed: ()
setState(()
AppToaster.pop(ToasterType.info, "Delete");
listItems.removeAt(0);
);
,
),
),
SizedBox(width: UIConstants.s1),
Expanded(
flex: 1,
child: BlueButtonWithIcon(
text: 'Export',
icon: 'assets/icons/export.svg',
onPressed: null,
),
)
],
),
),
SizedBox(height: UIConstants.s1)
],
);
【问题讨论】:
你在哪里声明了listItems
?
我已经编辑了代码。可以看看吗?
【参考方案1】:
调用 setState 并不意味着颤振实际上会完全重绘屏幕,这意味着它将检查您的小部件树与最后渲染的小部件树,它只会绘制差异,它首先比较小部件类型,然后是小部件键发现当前小部件和前一个小部件之间存在差异,因此,当您从项目列表中删除一个项目时,颤动会检查您返回的小部件到当前呈现的小部件,它没有发现任何差异,也不会重新绘制屏幕并继续显示最后一次渲染
因此,为了让您告诉颤振 listView 中的一个项目已更改,您可以为每个列表项小部件分配一个 uniqueKey 键,请注意,对于这个主题,您的键对于该小部件的数据应该是唯一的,否则您将面临性能问题,因为如果您的小部件键被更改而该小部件的表示在下次调用该构建方法时没有任何变化,这可能经常发生颤振将小部件键与呈现到屏幕并存在于上的前一个小部件键进行比较渲染树,它发现键不同,它会重新绘制该小部件,这是一个冗余操作,因为您的小部件 UI 和表示是相同的
例如,根据数据的索引或内容为 listItems 中的每个数据模型分配一个唯一 id,并使用它为该数据表示的小部件创建 ValueKey()
这是一个列表的工作示例,当您单击列表项时,第一个列表项将被删除
class ListItemDataModel
final String id;
final Color color;
ListItemDataModel(this.id, this.color);
class _MyHomePageState extends State<MyHomePage>
List<ListItemDataModel> items = [];
@override
void initState()
super.initState();
items = [
ListItemDataModel("A", Colors.red),
ListItemDataModel("B", Colors.amber),
ListItemDataModel("C", Colors.green),
ListItemDataModel("D", Colors.lightBlueAccent),
ListItemDataModel("E", Colors.pink),
];
@override
Widget build(BuildContext context)
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Container(
child: ListView.builder(
itemBuilder: (context, index)
return GestureDetector(
key: ValueKey(items[index].id),
//Tap to Remove first item from list
onTap: ()
items.removeAt(0);
setState(() );
,
child: Container(
height: 60,
color: items[index].color,
child: Center(
child: Text(
"This is a unique item with id = $items[index].id"),
),
),
);
,
itemCount: items.length,
),
),
);
【讨论】:
我试过用钥匙,但我无法让它工作。我应该向哪个小部件添加 Key? 到第一级小部件,我会用一个例子来更新我的答案【参考方案2】:所以,
我们无法访问上面的代码.. 所以.. listItems 是从哪里来的? 也许您在初始化状态后检索 listItems 的值?如果是这样,您总是检索到相同的结果是正常的..
你应该做的是:
从参数、全局变量、数据库 ecc 中获取 listItems 值 显示列表 当您删除单个项目时,您应该更新原始列表 现在状态已更新,列表将加载更新后的值如果您从列表中删除了一个项目,但该列表随后以原始形式重新加载,您的更新将丢失
【讨论】:
感谢您的评论。我更新了代码以显示我在哪里获取 listItems。它来自 API 调用,我做了一些映射来过滤值。以上是关于如何在 Flutter 中删除列表视图顶部的项目?的主要内容,如果未能解决你的问题,请参考以下文章