networkImageRender function
Implementation
CustomRender networkImageRender({
Map<String, String>? headers,
String Function(String?)? mapUrl,
double? width,
double? height,
Widget Function(String?)? altWidget,
Widget Function()? loadingWidget,
}) =>
CustomRender.widget(widget: (context, buildChildren) {
final src = mapUrl?.call(_src(context.tree.element!.attributes.cast())) ??
_src(context.tree.element!.attributes.cast())!;
Completer<Size> completer = Completer();
if (context.parser.cachedImageSizes[src] != null) {
completer.complete(context.parser.cachedImageSizes[src]);
} else {
Image image = Image.network(src, frameBuilder: (ctx, child, frame, _) {
if (frame == null) {
if (!completer.isCompleted) {
completer.completeError("error");
}
return child;
} else {
return child;
}
});
ImageStreamListener? listener;
listener =
ImageStreamListener((ImageInfo imageInfo, bool synchronousCall) {
var myImage = imageInfo.image;
Size size = Size(myImage.width.toDouble(), myImage.height.toDouble());
if (!completer.isCompleted) {
context.parser.cachedImageSizes[src] = size;
completer.complete(size);
image.image.resolve(const ImageConfiguration()).removeListener(listener!);
}
}, onError: (object, stacktrace) {
if (!completer.isCompleted) {
completer.completeError(object);
image.image.resolve(const ImageConfiguration()).removeListener(listener!);
}
});
image.image.resolve(const ImageConfiguration()).addListener(listener);
}
final attributes =
context.tree.element!.attributes.cast<String, String>();
final widget = FutureBuilder<Size>(
future: completer.future,
initialData: context.parser.cachedImageSizes[src],
builder: (BuildContext buildContext, AsyncSnapshot<Size> snapshot) {
if (snapshot.hasData) {
return Container(
constraints: BoxConstraints(
maxWidth: width ?? _width(attributes) ?? snapshot.data!.width,
maxHeight:
(width ?? _width(attributes) ?? snapshot.data!.width) /
_aspectRatio(attributes, snapshot)),
child: AspectRatio(
aspectRatio: _aspectRatio(attributes, snapshot),
child: Image.network(
src,
headers: headers,
width: width ?? _width(attributes) ?? snapshot.data!.width,
height: height ?? _height(attributes),
frameBuilder: (ctx, child, frame, _) {
if (frame == null) {
return altWidget?.call(_alt(attributes)) ??
Text(_alt(attributes) ?? "",
style: context.style.generateTextStyle());
}
return child;
},
),
),
);
} else if (snapshot.hasError) {
return altWidget
?.call(_alt(context.tree.element!.attributes.cast())) ??
Text(_alt(context.tree.element!.attributes.cast()) ?? "",
style: context.style.generateTextStyle());
} else {
return loadingWidget?.call() ?? const CircularProgressIndicator();
}
},
);
return Builder(
key: context.key,
builder: (buildContext) {
return GestureDetector(
child: widget,
onTap: () {
if (MultipleTapGestureDetector.of(buildContext) != null) {
MultipleTapGestureDetector.of(buildContext)!.onTap?.call();
}
context.parser.onImageTap?.call(
src,
context,
context.tree.element!.attributes.cast(),
context.tree.element);
},
);
});
});