首页 > 解决方案 > Flutter setState()不适用于GridView中的小部件

问题描述

我有一个非常基本的小部件,在调用 setState 时不会重建。我已经搜索并尝试了我能想到的一切。我一定是忽略了什么。如果我在 Android Studio 中设置断点,我可以看到该值确实发生了变化,但它没有被重建或重新呈现,也没有被它的调用覆盖。

这是有问题的小部件。

import 'package:flutter/material.dart';

class NewestCommunityImagesWidget extends StatefulWidget {
  String id;
  String image;
  String userSlug;
  String username;
  int likes;
  // String created_at;
  bool is_favorited;
  Function upvoteCommunityImages;
  Function flagCommunityImages;

  NewestCommunityImagesWidget({
    this.id,
    this.image,
    this.userSlug,
    this.username,
    this.is_favorited,
    this.upvoteCommunityImages,
    this.flagCommunityImages,
    this.likes,
  });

  @override
  _NewestCommunityImagesWidgetState createState() =>
      _NewestCommunityImagesWidgetState();
}

class _NewestCommunityImagesWidgetState
    extends State<NewestCommunityImagesWidget>
    with AutomaticKeepAliveClientMixin {
  @override
  bool get wantKeepAlive => true;

  @override
  Widget build(BuildContext context) {
    super.build(context);
    return Card(
      child: Container(
          padding: EdgeInsets.only(top: 8),
          child: Column(children: [
            Image.network(widget.image),
            Container(
              margin: EdgeInsets.only(left: 5),
              child: IconButton(
                icon: Icon(
                    widget.is_favorited
                        ? Icons.favorite
                        : Icons.favorite_border,
                    color: widget.is_favorited ? Colors.red : Colors.black),
                onPressed: () {
                  setState(() {
                    widget.is_favorited = !widget.is_favorited;
                  });
                  widget.upvoteCommunityImages();
                },
              ),
            )
          ])),
    );
  }
}

这是我渲染小部件的方式。

GridView.builder(
                  shrinkWrap: true,
                  padding: const EdgeInsets.all(5),
                  itemCount: community_images.length,
                  itemBuilder: (ctx, index) => NewestCommunityImagesWidget(
                      id: community_images[index].id.toString(),
                      image: community_images[index].image,
                      userSlug: community_images[index].userSlug,
                      username: community_images[index].username,
                      // created_at: community_images[index].created_at,
                      likes: community_images[index].likes,
                      is_favorited: community_images[index].favorited,
                      upvoteCommunityImages: () {
                        upvoteCommunityImage(
                            community_images[index].id.toString());
                      },
                      flagCommunityImages: () {
                        flagCommunityImage(
                            context, community_images[index].id.toString());
                      }),
                  gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
                      crossAxisCount: 2,
                      crossAxisSpacing: 1,
                      mainAxisSpacing: 1,
                      childAspectRatio: 20 / 30),
                )

我有一个类似的评论小部件,具有相同的功能,可以正常工作...感谢您的额外眼睛,让我知道您是否需要其他信息来调试它。

标签: fluttersetstate

解决方案


你需要一个Function来改变favorite状态,比如upvoteCommunityImagesflagCommunityImages函数

Function(bool newFavoriteState) changeFavotireState;
//in NewestCommunityImagesWidget widget
IconButton(
            icon: Icon(
                widget.is_favorited
                    ? Icons.favorite
                    : Icons.favorite_border,
                color: widget.is_favorited ? Colors.red : Colors.black),
            onPressed: () { 
              widget.is_favorited = !widget.is_favorited;
              widget.changeFavotireState(widget.is_favorited); 
              widget.upvoteCommunityImages();
            },
          ),

// outside 
NewestCommunityImagesWidget(changeFavotireState:(newFavoriteState){
    setState(){
       community_images[index].favorited = newFavoriteState;
    };
 });

将您在构造函数中传递的值保留为默认值。

它在外面没有变化的原因是:is_favorited成为引用内存中的另一个地方


推荐阅读