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

时间:2020-04-14 15:16:09

标签: flutter dart flutter-layout

我正在Flutter中构建一个应用程序,该应用程序应该是类似于faceboook的社交网络应用程序。 enter image description here 我实现了一个类似的按钮-按下该按钮时向服务器发送请求,然后根据状态代码设置状态。我的问题开始于setState()再次呈现头像图片,或从头开始再次创建头像时(头像存储在64base字符串中)。 likePress是发送请求的未来,然后相应地设置布尔值isLiked。 这是“赞”按钮的创建:

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) {});
          });
        }
      },
    );
  }

这是头像的创建:

createAvatar(BuildContext context, avatar_base64, int ownerId) {
    Uint8List bytes = base64Decode(avatar_base64.split(',').last);

    return RepaintBoundary(
        child: CircleAvatar(
      radius: 25.0,
      backgroundImage: MemoryImage(bytes),
      backgroundColor: Colors.transparent,
    ));
  }

将它们一起显示的小部件是我为此项目创建的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),
                ],
              )),
        ));
  }

postInfo只是一个FutureBuilder,用于构建将头像和名称加起来的ListTile,createButtonBar创建了like按钮和2个其他按钮。

我想在用户按下“赞”按钮时更改图标,但前提是服务器响应了正确的状态代码并且没有渲染并再次创建整个Post小部件。谢谢您。麻烦!

2 个答案:

答案 0 :(得分:1)

这意味着头像在您调用 setState((){})的位置的下方。在您的情况下,该方法可能在该特定小部件内,并且该小部件正在重建。

我建议您解决问题,以将头像的创建移到上方。这样,如果您需要重建对象,则不会重新创建化身,而只是将其放置在新的小部件中。放置一些 debugPrint 可以加快该过程,并尝试重构代码以查看是否丢失了某些东西。

答案 1 :(得分:0)

仔细检查代码后,我决定为帖子的每个部分创建一个不同的Widget,以便可以初始化在build方法之外将不再构建的所有内容。


因此,如果要从setState()方法中排除窗口小部件,则需要将其移动到当前窗口小部件之外(通过为其创建窗口小部件)并将其实例作为参数创建在构造函数中。


更详细地讲,我创建了一个名为PostHeader的类,并在其中创建了化身和包含它的ListTile,然后在Post类内创建了它的实例,因此它不是在build类的Post方法内部创建的。