我知道我可以在包含this.setState()
的父状态小部件屏幕上使用ListView.builder
来使ListView重建其列表。
问题是我使用另一个子状态小部件来构建每个ListView项。 Flutter文档说,只要遇到相同的小部件,树构建就会停止。这使得ListView内容不会重建。
如何在不指定键(全局键/本地键)之类的情况下强制ListView使所有子级“无效”并强制重建整个内容?
编辑:简化代码。
class PostList extends extends StatefulWidget {
final UserModel user;
PostList({ this.user }): super();
@override
_PostListState createState() => _PostListState();
}
class _PostListState extends State<PostList> {
UserModel _user;
List<PostModel> _posts;
final _repository = Repository();
@override
void initState() {
_user = widget.user;
_repository.fetchPosts(userId: user.id)
.then((response) => this.setState(() => _posts = response)
.catchError((onError) => debugPrint(onError);
}
addNewRandomPost() {
final newPost = PostModel(text: DateTime.now().millisecondsSinceEpoch.toString());
this.setState(() => _posts = [newPost]..addAll(_posts ?? []));
}
@override
Widget build(BuildContext context) {
return Scaffold(appBar: AppBar(title: "Post list"),
body: ListView.builder(
itemCount: (_posts?.length ?? 0) + 1,
itemBuilder: (context, index) {
if (index == 0)
return RaisedButton(child: Text("Add new random post"), onPressed: addNewRandomPost);
else if(_posts == null)
return Center(child: CircularProgressIndicator());
else
return PostCard(post: _posts[index - 1]);
}
)
}
}
class PostCard extends StatefulWidget {
final PostModel post;
PostCard ({ this.post }): super();
@override
_PostCardState createState() => _PostCardState();
}
class _PostCardState extends State<PostCard> {
PostModel _post;
@override
void initState() {
_post = widget.post;
}
@override
Widget build(BuildContext context) => Card(child:
Padding(padding: EdgeInsets.all(10), child: Text(_post.text));
}
PostCard
小部件显然还有更多的代码和用途,我有意将其作为有状态小部件而不是无状态小部件。但是我只是在这里简化了它,以表明即使使用此简单代码,只要点击“添加新随机帖子”,就可以:
_posts
不为空),如果我在列表的开头添加新帖,则已经创建的现有明信片不会更改。它仅在列表的底部添加新的明信片小部件,显示列表中的最后一个帖子,具有讽刺意味的是,第一个数据被推送到最后一个。因此,即使帖子的内容实际上彼此不同,所有的明信片都显示相同的数据。五次单击按钮后,我期望什么:
[ Add new random post ]
1580789378
1580789373
1580789363
1580789349
1580789332
我得到的是
[ Add new random post ]
1580789332
1580789332
1580789332
1580789332
1580789332
答案 0 :(得分:0)
您可以这样做
List your_data_container;
_yourDeleteMethod()async{
*your way of deleting*
if(response.statuscode == 200){
_fetchListContent();
}
}
_yourUpdateMethod()async{
*your way of Updating*
if(response.statuscode == 200){
_fetchListContent();
}
}
_fetchListContent()async{
*your way of fetching*
if(response.statuscode==200){
fetched_data = json.decode(response.body);
setState((){
your_data_container = *fetched_data*;
})
}
}
ListView.builder(
itemCount: your_data_container.length,
itemBuilder: (context, index){
return Container(
width: screenWidth,
height: screenHeight/15,
child: Row(
children: <Widget>[
Expanded(
child: Text(index.toString)
),
IconButton(
icon: Icon(Icons.delete, color: Colors.red)
onPressed: (){
_yourDeleteMethod();
}
),
IconButton(`
icon: Icon(Icons.edit)
onPressed: (){
_yourUpdateMethod();
}
)
]
)
);
}
)
注意:ListView.builder应该在内部版本中或作为小部件使用,这只是为了告诉您这不是完整的代码