Flutter 如何在没有父控件的情况下在flatter中重新加载特定的小部件?

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

我正在Flitter中构建一个应用程序,它应该是一个类似faceboook的社交网络应用程序。 当按下向服务器发送请求时,我实现了一个like按钮,然后根据状态代码设置状态。当setState()再次渲染化身图片或从头开始创建它时,我的问题就开始了(化身存储在64base字符串中)。 likePress是发送请求,然后相应地设置布尔值
的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),
                ],
              )),
        ));
  }