Taking into account this answer on how to get a widgets size, you can come up with the following approach to resize the image cache in memory to about twice the widgets size. I've found that if you directly use the widgets size the image loses A LOT of sharpness. You would also probably start adding most of cachedNetworkImage attributes to AutoSizedCachedNetworkImage
in order to have a more customizable widget.
TLDR:
This will adjust the image size after first frame.
class AutoSizedCachedNetworkImage extends StatefulWidget {
final String url;
const AutoSizedCachedNetworkImage({Key? key, required this.url}) : super(key: key);
@override
State<AutoSizedCachedNetworkImage> createState() => _AutoSizedCachedNetworkImageState();
}
class _AutoSizedCachedNetworkImageState extends State<AutoSizedCachedNetworkImage> {
double? imageSizeWidth;
double? imageSizeHeight;
@override
Widget build(BuildContext context) {
return MeasureSize(
onChange: (size) {
if (mounted) {
setState(() {
imageSizeWidth = size.width * 2;
imageSizeHeight = size.height * 2;
});
}
},
child: CachedNetworkImage(
memCacheHeight: imageSizeHeight?.toInt(),
memCacheWidth: imageSizeWidth?.toInt(),
imageUrl: widget.url,
),
);
}
}
Code sourced from the other answer to get a widget's size
typedef void OnWidgetSizeChange(Size size);
class MeasureSizeRenderObject extends RenderProxyBox {
Size? oldSize;
final OnWidgetSizeChange onChange;
MeasureSizeRenderObject(this.onChange);
@override
void performLayout() {
super.performLayout();
var newSize = child!.size;
if (oldSize == newSize) return;
oldSize = newSize;
WidgetsBinding.instance!.addPostFrameCallback((_) {
onChange(newSize);
});
}
}
class MeasureSize extends SingleChildRenderObjectWidget {
final OnWidgetSizeChange onChange;
const MeasureSize({
Key? key,
required this.onChange,
required Widget child,
}) : super(key: key, child: child);
@override
RenderObject createRenderObject(BuildContext context) {
return MeasureSizeRenderObject(onChange);
}
}