【问题标题】:Image widget not rebuilding on setState图像小部件未在 setState 上重建
【发布时间】:2020-11-11 14:54:28
【问题描述】:

我正在尝试在我的颤振应用中实现搜索。它就像一个电子商务应用程序,带有每个产品的图像和名称。搜索应该使用输入的查询从列表中过滤掉产品。好吧,它工作正常,但只有文本小部件被重建。图像不仅仅移动文本;更像是说图像小部件即使在有状态小部件中也不会重建。我观察到GetImg() 小部件是我为获取图像而构建的自定义小部件,实际上只有在有新东西要构建时才会调用。例如。如果我的屏幕上已经有 10 个匹配项,并且我在搜索输入中输入了更多字符,则会显示较少的匹配结果,但不会重建 GetImg() 小部件,这使得已经构建的图像即使在它们存在时也会保持在它们的位置应该重建和改变。 GetImg() 小部件仅在我退格并显示更多匹配项时构建。请注意,它实际上并没有构建已经存在的图像,而是构建了新的图像。我只是希望我的问题得到理解。

这是我的搜索功能:

List filterProducts(String text, List items) {
    List searchedList = items
        .where((item) =>
            item.title
                .toString()
                .toLowerCase()
                .contains(text.trim().toLowerCase()) ||
            item.price
                .toString()
                .toLowerCase()
                .contains(text.trim().toLowerCase()))
        .toList();
    return searchedList;
}

这就是我循环它们的方式:

Widget build(BuildContext context) {
return GestureDetector(
  onTap: () {},
  child: Column(
    crossAxisAlignment: CrossAxisAlignment.start,
    children: <Widget>[
      Expanded(
        child: Container(
          decoration: BoxDecoration(
            borderRadius: BorderRadius.circular(16),
          ),
          child: Hero(
            tag: widget.product.id,
            child: ClipRRect(
              borderRadius: BorderRadius.circular(8.0),
              child: GetImage(widget.product.images[0]), // GetImage is the widget class I fetch images with; and it does not rebuild
            ),
          ),
        ),
      ),
      Text(
        formatPrice(widget.product.price),
        style: TextStyle(fontWeight: FontWeight.bold),
      ) // the Text widget rebuilds adequately
    ],
  ),
);
}

GetImage 文件(如有必要):

class GetImage extends StatefulWidget {
  final String productName;

  GetImage(this.productName);

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

class _GetImageState extends State<GetImage> {
  StorageReference photoRef =
      FirebaseStorage.instance.ref().child('productImages');
  Uint8List imageFile;

  getImage() {
    if (!requestedIndexes.contains(widget.productName)) {
      int maxSize = 1 * 1024 * 1024;
      photoRef.child(widget.productName).getData(maxSize).then((data) {
        if (mounted) {
          setState(() {
            imageFile = data;
          });
        }
        imageData.putIfAbsent(widget.productName, () {
          return data;
        });
      }).catchError((error) {
        debugPrint(error.toString());
      });
      requestedIndexes.add(widget.productName);
    }
  }

  Image displayImage() {
    dynamic size = MediaQuery.of(context).size;
    if (imageFile == null) {
      return Image.asset(
        'assets/icons/loader.gif',
        height: size.height,
        width: size.width * 0.5,
        fit: BoxFit.cover,
      );
    } else {
      return Image.memory(
        imageFile,
        height: size.height,
        width: size.width * 0.5,
        fit: BoxFit.cover,
      );
    }
  }

  @override
  void initState() {
    super.initState();
    if (!imageData.containsKey(widget.productName)) {
      getImage();
    } else {
      if (mounted) {
        setState(() {
          imageFile = imageData[widget.productName];
        });
      }
    }
  }

  @override
  Image build(BuildContext context) {
    return displayImage();
  }
}

【问题讨论】:

    标签: flutter dart search


    【解决方案1】:

    您在 initState 中调用 getImage 并且它不会更新图像,因为它没有在构建中调用。更新产品名称时,构建功能不会引用更新的产品名称。这只是原因。如果可能,请在 build 中调用 getImage 函数。

    【讨论】:

    • 谢谢。这帮助我弄清楚了这个问题。确实,getImage 没有运行,并且 imageFile 没有使用当前产品名称的 imageData 进行更新。我必须在构建中设置状态
    猜你喜欢
    • 2021-09-19
    • 2020-09-20
    • 2019-01-14
    • 1970-01-01
    • 2020-08-02
    • 1970-01-01
    • 1970-01-01
    • 2020-11-09
    • 1970-01-01
    相关资源
    最近更新 更多