我正在尝试在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();
}
}
答案 0 :(得分:1)
您正在initState中调用getImage,它将不会更新图像,因为它未在build中调用。更新产品名称时,构建功能不会引用更新的产品名称。这就是原因。如果可能,请在构建中调用getImage函数。