Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/visual-studio-2008/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
List 如何在不重建整个列表的情况下更新列表项_List_Flutter_Listview_Dart_Key - Fatal编程技术网

List 如何在不重建整个列表的情况下更新列表项

List 如何在不重建整个列表的情况下更新列表项,list,flutter,listview,dart,key,List,Flutter,Listview,Dart,Key,有人问了我这个问题,我想让大家知道答案 如何在不重建整个列表的情况下更新列表项 一个典型的用例(我将在下面的回答中重复) 可能是一个列表视图,它接收小部件的列表,可能来自API向列表中的小部件提供一个键将阻止这些操作 从小部件树中删除,并因此进行不必要的重建 你可以试着运行这个 记录终端中的日志 代码发布在下面 导入'dart:async'; 进口“包装:颤振/材料.省道”; void main()=>runApp(MyApp()); 类MyApp扩展了StatefulWidget{ @凌驾 _

有人问了我这个问题,我想让大家知道答案

如何在不重建整个列表的情况下更新列表项

一个典型的用例(我将在下面的回答中重复)


可能是一个
列表视图
,它接收
小部件
列表
,可能来自
API

列表中的
小部件
提供一个
将阻止这些操作

从小部件树中删除,并因此进行不必要的重建

你可以试着运行这个

记录终端中的日志

代码发布在下面

导入'dart:async';
进口“包装:颤振/材料.省道”;
void main()=>runApp(MyApp());
类MyApp扩展了StatefulWidget{
@凌驾
_MyAppState createState()=>\u MyAppState();
}
类MyAppState扩展了状态{
最终_navigatorKey=GlobalKey();
假api(美国石油学会api);
@凌驾
void initState(){
_api=伪造api(_导航作业);
super.initState();
}
@凌驾
无效处置(){
_api?.dispose();
super.dispose();
}
@凌驾
小部件构建(构建上下文)=>MaterialApp(
导航工作:_导航工作,
主页:MyInheritedWidget(
api:_api,
子项:const MyHomePage(),
),
);
}
类MyInheritedWidget扩展了InheritedWidget{
常量MyInheritedWidget({
@必需的小部件子项,
@需要此.api,
}):超级(
key:const key('MyInheritedWidget'),
孩子:孩子,
);
最终伪造api;
的静态MyInheritedWidget(BuildContext上下文)=>
dependOnInheritedWidgetOfExactType();
@凌驾
bool updateShouldNotify(MyInheritedWidget old)=>false;
}
类MyHomePage扩展了无状态小部件{
const MyHomePage():super(key:const key('MyHomePage');
@凌驾
小部件构建(构建上下文)=>Builder(
生成器:(上下文)=>Scaffold(
背景颜色:颜色。蓝灰色,
正文:StreamBuilder(
stream:MyInheritedWidget.of(context).api.stream,
初始数据:[],
生成器:(上下文,列表)=>list.hasError
?常数中心(子:图标(图标错误))
:!list.hasData
?常数中心(子项:循环压缩机指示器())
:list.data.isEmpty
?康斯特中心(
子:文本(
'列表为空',
textScaleFactor:1.5,
))
:ListView.builder(
itemCount:list.data.length,
itemBuilder:(上下文,索引)=>list.data[index],
),
),
浮动操作按钮:浮动操作按钮(
背景颜色:Colors.white,
子项:常量图标(Icons.add,颜色:Colors.blueGrey),
onPressed:MyInheritedWidget.of(context).api.add,
),
),
);
}
类ItemWidget扩展了无状态Widget{
ItemWidget(this.text):super(key:UniqueKey());
最终字符串文本;
@凌驾
小部件构建(构建上下文){
打印('Item$text is building');
返回中心(
子:容器(
填充:仅限常量边集(底部:20),
宽度:MediaQuery.of(context).size.width*.5,
孩子:卡片(
标高:10,
孩子:ListTile(
引导:手势检测器(
子:常量图标(Icons.edit),
onTap:()=>MyInheritedWidget.of(context.api.edit(key),
),
跟踪:手势检测器(
子:常量图标(Icons.delete),
onTap:()=>MyInheritedWidget.of(context.api.delete(key),
),
标题:文本(Text),
),
),
),
);
}
}
类ItemDialog扩展StatefulWidget{
const ItemDialog({this.text});
最终字符串文本;
@凌驾
_ItemDialogState createState()=>\u ItemDialogState();
}
类_ItemDialogState扩展状态{
TextEditingController\u控制器;
@凌驾
void initState(){
_controller=TextEditingController()…text=widget.text;
super.initState();
}
@凌驾
无效处置(){
_控制器?.dispose();
super.dispose();
}
@凌驾
小部件构建(构建上下文)=>AlertDialog(
内容:堆栈(
对齐:对齐.center,
儿童:[
容器(
宽度:double.infinity,
高度:MediaQuery.of(context).size.height*.3,
儿童:中心(
孩子:TextField(
自动对焦:对,
控制器:_控制器,
),
),
),
],
),
行动:[
图标按钮(
onPressed:()=>Navigator.pop(上下文,_controller.text??“”),
图标:常量图标(Icons.save),
),
],
);
}
类伪造API{
伪造API(这是一种导航技术);
最后的环球航行;
最终_列表=[];
流控制器(StreamController);;
StreamController获取\u c=>
_控制器???=StreamController.broadcast();
Stream get Stream=>\u c.Stream;
void dispose()=>_controller?.close();
作废删除(键){
_list.removeWhere((ItemWidget项)=>item.key==key);
_c、 添加(_列表);
}
无效编辑(键)异步{
final _item=_list.firstWhere((ItemWidget item)=>item.key==key);
最终索引=\u list.lastIndexOf(\u项);
最终文本=等待显示对话框(
上下文:navigatorKey.currentState.overlay.context,
生成器:(上下文)=>ItemDialog(
text:_item.text,
),
);
_列表.删除(_索引);
_插入(_索引,ItemWidget(_文本));
_c、 添加(_列表);
}
void add()异步{
最终文本=等待显示对话框(