【发布时间】: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();
}
}
【问题讨论】: