Flutter listview:移除一个Item时,下一个继承一些属性
Posted
技术标签:
【中文标题】Flutter listview:移除一个Item时,下一个继承一些属性【英文标题】:Flutter listview: when removing an Item, the next one inherits some properties 【发布时间】:2019-11-16 19:24:04 【问题描述】:我正在开发一个项目,其中有一个名为 AlarmCard 的自定义小部件的 ListView,每个小部件都填充了警报对象的信息。 AlarmCard 有两个布尔属性:Expanded 和 Loading,这是主要代码:
class _AlarmCardState extends State<AlarmCard>
bool _expanded = false;
bool _loading = false;
static const double iconSize = 28.0;
static const Color iconColor = Colors.black87;
static const TextStyle fieldTextStyle = TextStyle(
fontSize: 16.0,
fontWeight: FontWeight.w400,
color: Color.fromRGBO(0, 0, 0, 0.6),
);
static const TextStyle clearFieldTextStyle = TextStyle(
fontSize: 16.0,
fontWeight: FontWeight.w400,
color: Color.fromRGBO(0, 0, 0, 0.2),
);
@override
Widget build(BuildContext context)
TextStyle timeTextStyle = TextStyle(
fontSize: 54.0,
fontWeight: FontWeight.w400,
color: Colors.black54,
);
Widget card = Card(
child: Column(
children: <Widget>[
Opacity(
opacity: _loading ? 1.0 : 0.0,
child: Container(
height: 3.0,
child: ClipRRect(
child: LinearProgressIndicator(),
borderRadius: BorderRadius.only(
topRight: Radius.circular(3.0),
topLeft: Radius.circular(3.0),
),
),
),
),
Padding(
padding: const EdgeInsets.fromLTRB(12.0, 8.0, 12.0, 8.0),
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Row(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
mainAxisSize: MainAxisSize.max,
children: <Widget>[
Padding(
padding: const EdgeInsets.only(top: 6.0, bottom: 8.0),
child: InkWell(
onTap: () => _selectTime(context),
child: Text(widget.alarm.timeString, style: timeTextStyle)
),
),
Switch(value: widget.alarm.enabled, onChanged: _onAlarmEnabledChange),
],
),
AnimatedCrossFade(
firstChild: _getContractedBottom(),
secondChild: _getExpandedBottom(),
duration: Duration(milliseconds: 200),
crossFadeState: _expanded ? CrossFadeState.showSecond : CrossFadeState.showFirst,
)
],
),
),
],
),
);
return _loading ?
Opacity(
opacity: 0.6,
child: IgnorePointer(
child: card
),
)
: card;
...
当然,还有一些自定义小部件,例如 DayToggle,以及返回小部件的 _getContractedBottom() 和 _getExpandedBottom() 方法。
一旦我们定义了依赖 _expanded 和 _loading 的 AlarmCard 构建方法,我们使用 final List<Alarm> alarmList
构建 ListView:
ListView.builder(
itemCount: alarmList.length,
itemBuilder: (BuildContext context, int i)
Alarm alarm = alarmList[i];
return AlarmCard(
alarm: alarm,
ringtones: ringtoneList,
onAlarmUpdated: () => true,
onAlarmDeleted: ()
setState(()
alarmList.remove(alarm);
);
return true;
);
,
)
所以,ListView 完美地工作,并且每个项目都按原样显示,它可以扩展和更新(以便 _loading 变为 true)。删除项目时会出现问题。
想象一下alarmList 有8 个条目,它们都显示在屏幕上,我们只展开和删除第6 个条目。当我们按下Delete的那一刻,AlarmCard变成Loading状态,然后被删除,但是一旦从ListView中移除,第7项“继承”了_expanded和_loading属性,所以它显示了与它的alarm对应的正确信息,但它不应该被扩展和加载。
有人知道问题出在哪里吗? 我一直在搜索多个网站和 *** 帖子,但找不到这个问题。 非常感谢!
【问题讨论】:
尝试 setState(() list = List.from(list) ..removeAt(index); ); @Vineet 不,我刚刚尝试过,我得到了同样的错误 您找到解决方案了吗?我刚刚遇到了完全相同的问题,并且正在弹出这个问题时提出一个问题 如果我没记错的话,我认为我过去修复它的方法是在每个 ListItem 中使用 UniqueKey。你可以在这里获得更多信息youtu.be/kn0EOS-ZiIc 【参考方案1】:正如@javired98 所说,问题很关键。那个视频对我有帮助。但请记住,如果您有小部件列表,则当您将其添加到未在小部件类中定义的列表时,密钥必须传递给小部件。
imageList.add(ImageElement(
key:ValueKey(imageCounter),
id: ...,
imgURL: ...,
.
.
.
));
【讨论】:
视频地址:youtu.be/kn0EOS-ZiIc以上是关于Flutter listview:移除一个Item时,下一个继承一些属性的主要内容,如果未能解决你的问题,请参考以下文章
flutter listview item滚出屏幕不重置状态
Flutter 仿企业微信多选-listview可见item位置