图像小部件未在setState上重建

时间:2020-11-11 14:54:28

标签: flutter dart search

我正在尝试在Flutter应用中实现搜索。就像是一个电子商务应用程序,其中包含图像和每个产品的名称。该搜索应该使用输入的查询从列表中过滤掉产品。好吧,它工作正常,但仅重建了文本小部件。图像不仅移动文本,还移动文本。更像说图像窗口小部件即使在有状态窗口小部件中也不会重建。我观察到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();
  }
}

1 个答案:

答案 0 :(得分:1)

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