如何解决Flutter 列表视图更新不正确
我正在使用 Flutter ListView 测试动态行列表,其中在删除所选行后项目未正确显示。后端明智,指定索引处的数据被删除,但 ListView 将无法正确显示。我知道这与 Key 有关系,但经过数小时的反复试验和 Google 搜索,问题仍然无法解决。
有什么我错过的吗?以下是我采取的行动过程:
- 将 UniqueKey / Key 放在 ListView.Builder 下(例如 Key(_fieldList.length.toString()))。
- 将 ObjectKey / ValueKey / Key 放在 dismissible 或我的自定义行小部件下。
详情请参考 GIF。
[Sample screen recording]
https://i.stack.imgur.com/BEy1V.gif
以下是一些代码片段:
编辑屏幕
class EditFormScreen extends StatefulWidget {
final CustomForm _customForm;
final CustomFormBloc _bloc;
EditFormScreen(this._bloc,this._customForm);
static Future<void> show(
{BuildContext context,CustomFormBloc formBloc,CustomForm form}) async {
await Navigator.push(
context,MaterialPageRoute(
fullscreenDialog: false,builder: (_) => BlocProvider.value(
value: formBloc,child: EditFormScreen(formBloc,form),),);
}
@override
_EditFormScreenState createState() => _EditFormScreenState();
}
class _EditFormScreenState extends State<EditFormScreen> {
final GlobalKey<FormBuilderState> _fbKey = GlobalKey<FormBuilderState>();
List<CustomField> _fieldsList = [];
CustomForm _form;
@override
Widget build(BuildContext context) {
_form = widget._customForm ?? CustomForm();
return Scaffold(
appBar: MainAppBar(title: kEditFormScreen),floatingActionButton: FloatingActionButton(
child: Icon(Icons.add),onpressed: _addNewField,body: Container(
child: FormBuilder(
key: _fbKey,autovalidateMode: AutovalidateMode.onUserInteraction,child: BlocBuilder<CustomFormBloc,CustomFormState>(
builder: (context,state) {
return SingleChildScrollView(
child: Padding(
padding: EdgeInsets.all(16.0),child: Column(
children: [
FormBuilderTextField(
name: "title",maxLines: null,style: TextStyle(height: 1.5),decoration: Inputdecoration(labelText: kFormTitleText),valueTransformer: (value) => value.toString().trim(),]..add(
_buildCustomFields(),);
},);
}
_addNewField() {
_fieldsList.add(CustomField(fieldIdentifier: Uuid().v4()));
widget._bloc.add(
ModifyFieldFormEvent(CustomField(),true),);
}
Widget _buildCustomFields() => ListView.builder(
shrinkWrap: true,//key: UniqueKey(),physics: NeverScrollableScrollPhysics(),itemCount: _fieldsList.length,itemBuilder: (context,index) => dismissible(
//key: Key("field-${_fieldsList[index].fieldIdentifier}"),key: Key(_fieldsList[index].fieldIdentifier),background: Container(
alignment: Alignment.centerRight,child: Padding(
padding: EdgeInsets.all(8.0),child: Text(
"Delete",style: TextStyle(color: Colors.white,fontSize: 18.0),color: Colors.red),direction: dismissDirection.endToStart,confirmdismiss: (direction) async {
_fieldsList.removeAt(index);
widget._bloc.add(
ModifyFieldFormEvent(CustomField(),);
return true;
},child: FieldRow(
key: Key(_fieldList[index].fieldIdentifier)
item: _fieldsList[index],index: index,onMenuSelected: (value) => _handleMenuOnSelected(value,index),);
_handleMenuOnSelected(String value,int index) {
switch (value) {
case kEditFieldTitle:
print("Edit field title...");
break;
case kEditFieldType:
print("Edit field type...");
break;
case kDeleteField:
print("Deleted item: ${_fieldsList[index].fieldIdentifier}");
_fieldsList.removeAt(index);
widget._bloc.add(
ModifyFieldFormEvent(CustomField(),);
break;
default:
break;
}
}
}
行小部件
class FieldRow extends StatefulWidget {
final CustomField item;
final int index;
final Function(String) onMenuSelected;
FieldRow({Key key,this.index,this.onMenuSelected,this.item}) : super(key: key);
@override
_FieldRowState createState() => _FieldRowState();
}
class _FieldRowState extends State<FieldRow> {
@override
Widget build(BuildContext context) {
return Row(
children: [
Expanded(
child: FormBuilderTextField(
name: "field#${widget.index}",decoration: Inputdecoration(
border: InputBorder.none,labelText: "${widget.item.fieldIdentifier}"),PopupMenuButton<String>(
onSelected: widget.onMenuSelected,itemBuilder: (_) => kCustomFieldOptions
.map(
(option) => PopupMenuItem<String>(
child: Text(option),value: option,)
.toList(),],);
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。