I want to use the Material design icons of flutter in my program, for that, I need to use the Icon widget. I have one network image (NetworkImage widget) and I want to display the Material design icon if there is an empty URL.
Container(
width: 48.0,
height: 48.0,
decoration: BoxDecoration(
image: DecorationImage(
image: imgLink.isEmpty
? Icon(Icons.person_outline)
: NetworkImage(
imgLink,
),
),
borderRadius: BorderRadius.circular(10.0)),
),
it shows error as icons is not a subtype of ImageProvider. Now how I can convert Icon to ImageProvider or any other way.
The solution is to create your own provider that converts the icon:
import 'dart:ui' as ui;
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
class IconImageProvider extends ImageProvider<IconImageProvider> {
final IconData icon;
final double scale;
final int size;
final Color color;
IconImageProvider(this.icon, {this.scale = 1.0, this.size = 48, this.color = Colors.white});
@override
Future<IconImageProvider> obtainKey(ImageConfiguration configuration) => SynchronousFuture<IconImageProvider>(this);
@override
ImageStreamCompleter load(IconImageProvider key, DecoderCallback decode) => OneFrameImageStreamCompleter(_loadAsync(key));
Future<ImageInfo> _loadAsync(IconImageProvider key) async {
assert(key == this);
final recorder = ui.PictureRecorder();
final canvas = Canvas(recorder);
canvas.scale(scale, scale);
final textPainter = TextPainter(textDirection: TextDirection.ltr);
textPainter.text = TextSpan(
text: String.fromCharCode(icon.codePoint),
style: TextStyle(
fontSize: size.toDouble(),
fontFamily: icon.fontFamily,
color: color,
),
);
textPainter.layout();
textPainter.paint(canvas, Offset.zero);
final image = await recorder.endRecording().toImage(size, size);
return ImageInfo(image: image, scale: key.scale);
}
@override
bool operator ==(dynamic other) {
if (other.runtimeType != runtimeType) return false;
final IconImageProvider typedOther = other;
return icon == typedOther.icon && scale == typedOther.scale && size == typedOther.size && color == typedOther.color;
}
@override
int get hashCode => hashValues(icon.hashCode, scale, size, color);
@override
String toString() => '$runtimeType(${describeIdentity(icon)}, scale: $scale, size: $size, color: $color)';
}
This is a standard ImageProvider, all the stock ones look much like this. The actual conversion is inside _loadAsync(). Rather simple, just a normal Canvas operation to draw the icon as text (it is text, actually).
Image in BoxDecoration of Container only support the ImageProvider class which have
the following Implementers
AssetBundleImageProvider, FileImage, MemoryImage, NetworkImage, ResizeImage, ScrollAwareImageProvider so it doesn't support the icon widget because icon widget has its own IconData class so that's why flutter giving you error, "icons is not a subtype of ImageProvider".
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With