Flutter 如何在没有父控件的情况下在flatter中重新加载特定的小部件?
我正在Flitter中构建一个应用程序,它应该是一个类似faceboook的社交网络应用程序。 当按下向服务器发送请求时,我实现了一个like按钮,然后根据状态代码设置状态。当setState()再次渲染化身图片或从头开始创建它时,我的问题就开始了(化身存储在64base字符串中)。 likePress是发送请求,然后相应地设置布尔值Flutter 如何在没有父控件的情况下在flatter中重新加载特定的小部件?,flutter,dart,flutter-layout,Flutter,Dart,Flutter Layout,我正在Flitter中构建一个应用程序,它应该是一个类似faceboook的社交网络应用程序。 当按下向服务器发送请求时,我实现了一个like按钮,然后根据状态代码设置状态。当setState()再次渲染化身图片或从头开始创建它时,我的问题就开始了(化身存储在64base字符串中)。 likePress是发送请求,然后相应地设置布尔值的future。 这是创建like按钮的步骤: buildLikeButton(int ownerId, int postId) { return Repa
的future。
这是创建like按钮的步骤:
buildLikeButton(int ownerId, int postId) {
return RepaintBoundary(
child: FutureBuilder<bool>(
future: getLike(ownerId, postId),
builder: (BuildContext context, AsyncSnapshot<bool> snapshot) {
IconButton likeButton;
if (snapshot.hasData) {
isLiked = snapshot.data;
likeButton = createLikeButton(ownerId, postId);
} else if (snapshot.hasError) {
isLiked = false;
likeButton = createLikeButton(ownerId, postId);
print('the snapshot has an error ${snapshot.error}');
} else {
isLiked = false;
likeButton = createLikeButton(ownerId, postId);
}
return likeButton;
}));
}
createLikeButton(int ownerId, int postId) {
return IconButton(
icon: returnLikeIcon(isLiked),
color: Theme.of(context).accentColor,
onPressed: () async {
if (this.mounted) {
setState(() {
Future lol = likePress(ownerId, postId).then((onValue) {});
});
}
},
);
}
同时显示它们的小部件是我为这个项目创建的Post
小部件,这是它的构建功能:
Widget build(BuildContext context) {
return InkWell(
borderRadius: BorderRadius.circular(0.2),
child: Container(
decoration: BoxDecoration(boxShadow: [
BoxShadow(
color: Theme.of(context).primaryColor,
blurRadius: 1.0,
spreadRadius: 1.0, // has the effect of extending the shadow
offset: Offset(
5.0, // horizontal, move right 10
5.0, // vertical, move down 10
),
),
]),
child: Card(
elevation: 10.0,
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Flexible(
fit: FlexFit.loose,
child: postInfo(context, time, ownerId)),
Divider(
thickness: 1.0,
height: 10.0,
indent: 10.0,
endIndent: 10.0,
),
postContent(content),
Divider(
thickness: 1.0,
height: 10.0,
indent: 10.0,
endIndent: 10.0,
),
createButtonBar(ownerId, postId),
],
)),
));
}
小部件构建(构建上下文){
回墨槽(
边界半径:边界半径。圆形(0.2),
子:容器(
装饰:BoxEdition(boxShadow:[
箱形阴影(
颜色:主题。背景。原色,
半径:1.0,
spreadRadius:1.0,//具有延伸阴影的效果
偏移量:偏移量(
5.0,//水平,向右移动10
5.0,//垂直,向下移动10
),
),
]),
孩子:卡片(
标高:10.0,
子:列(
mainAxisSize:mainAxisSize.min,
儿童:[
灵活的(
适合:FlexFit.宽松,
子项:postInfo(上下文、时间、所有者ID)),
分隔器(
厚度:1.0,
身高:10.0,
缩进:10.0,
收尾缩进:10.0,
),
后内容(内容),
分隔器(
厚度:1.0,
身高:10.0,
缩进:10.0,
收尾缩进:10.0,
),
createButtonBar(所有者ID、职位ID),
],
)),
));
}
postInfo
只是一个FutureBuilder,它构建了将头像和姓名相加的列表,并且createButtonBar
创建了like按钮和另外两个按钮
我想在用户按下like按钮时更改图标,但前提是服务器已使用正确的状态代码进行响应,并且没有重新呈现和创建整个Post
小部件。谢谢您的帮助 这意味着化身位于调用setState((){})的点下方。在您的例子中,该方法可能位于该特定小部件中,并且该小部件正在重建
我建议你解决这个问题,把阿凡达的创建移到上面。这样,如果您需要重建对象,则不会重新创建化身,而只是将其放置在新的小部件中。放置一些debugPrints以加快进程,并尝试重构代码以查看是否遗漏了一些内容。在仔细查看了我的代码后,我决定为文章的每个部分创建一个不同的小部件,这样我就可以初始化在build
方法之外不会再次构建的所有内容
因此,如果要从setState()
方法中排除小部件,则需要将其移出当前小部件(通过为其创建小部件)并仅创建其实例作为构造函数中的参数。
更详细地说,我创建了一个名为PostHeader
的类,在那里我创建了头像和包含它的ListTile
,然后在Post
类中创建了它的一个实例,因此,它不是在Post
类的build
方法中创建的。仅设置更新的特定对象的状态。那么,为什么化身图片会再次呈现自身?我建议使用适当的实现,无论是bloc还是providers。通过这种方式,您可以正确地处理状态我不熟悉您的建议,将尝试阅读这些建议,但目前我仍然希望它能够正常工作,而无需再次编写所有内容。显然,整个构建方法是在调用setState()时运行的。是否有任何方法可以排除再次构建小部件?不,没有。正如文档所述,在某些情况下直接从框架调用build方法,其中包括setState方法。您最终可以将应用程序逻辑的一部分移动到initState方法,当它插入到小部件树中时,该方法在小部件的整个生命周期中只调用一次。
Widget build(BuildContext context) {
return InkWell(
borderRadius: BorderRadius.circular(0.2),
child: Container(
decoration: BoxDecoration(boxShadow: [
BoxShadow(
color: Theme.of(context).primaryColor,
blurRadius: 1.0,
spreadRadius: 1.0, // has the effect of extending the shadow
offset: Offset(
5.0, // horizontal, move right 10
5.0, // vertical, move down 10
),
),
]),
child: Card(
elevation: 10.0,
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Flexible(
fit: FlexFit.loose,
child: postInfo(context, time, ownerId)),
Divider(
thickness: 1.0,
height: 10.0,
indent: 10.0,
endIndent: 10.0,
),
postContent(content),
Divider(
thickness: 1.0,
height: 10.0,
indent: 10.0,
endIndent: 10.0,
),
createButtonBar(ownerId, postId),
],
)),
));
}