Quickie: AdaptiveImageProvider
Here’s a little snippet that I made a couple of years ago that seems to be following me from a Flutter project to another.
It’s a little class that I call AdaptiveImageProvider
:
import 'package:flutter/painting.dart';
class AdaptiveImageProvider extends ImageProvider {
AdaptiveImageProvider(String url) : _delegate = _resolve(url);
final ImageProvider _delegate;
static ImageProvider _resolve(String url) {
final uri = Uri.parse(url);
switch (uri.scheme) {
case 'asset':
final path = uri.toString().replaceFirst('asset://', '');
return AssetImage(path);
case 'file':
final file = File.fromUri(uri);
return FileImage(file);
case 'http':
case 'https':
return NetworkImage(url);
default:
throw ArgumentError('Unsupported scheme: ${uri.scheme}');
}
}
@override
ImageStreamCompleter load(Object key, DecoderCallback decode) =>
_delegate.load(key, decode);
@override
Future<Object> obtainKey(ImageConfiguration configuration) =>
_delegate.obtainKey(configuration);
}
You can give this class pretty much any URL and it will poop out an ImageProvider
that knows how to display an image using that URL.
“That’s cool, I guess. But why?”
Let’s imagine we have a widget called Avatar
.
We give it a url
that points to an image, and it will be displayed in the shape of a circle:
class Avatar extends StatelessWidget {
const Avatar({required this.url});
final String url;
@override
Widget build(BuildContext context) {
return ClipOval(
child: Image(
image: AdaptiveImageProvider(url),
width: 56,
height: 56,
fit: BoxFit.cover,
),
);
}
}
In our app, users can upload their own pictures to set as their avatars.
As such, there are three possible URLs that the Avatar
widget has to handle:
- user hasn’t uploaded their avatar image - use a preloaded image, e.g.
assets://images/person.png
- the user is offline - display a locally cached image, e.g.
file://path/to/image.png
- someone is viewing the users’ profile for the first time - display an image from the web, e.g.
https://example.com/images/abc123.png
The AdaptiveImageProvider
class makes this easy - just provide a url
and it will figure out how to display it.
And since it’s extending from the ImageProvider
class that comes from Flutter, you can use it with popular libraries,
such as cached_network_image and others.
Other use cases
Although the above use cases are the more common ones, the list of possible applications doesn’t end there.
Here are some more:
- making an in-memory mode of your app where nothing goes to server, where server sync is a premium feature
- running your app in a “lorem ipsum” mode with placeholder asset images to automate taking app store screenshots in multiple languages
- creating a “retail demo” version of your app for Apple, so that they can showcase it in Apple Stores (this actually happened at my previous workplace)
I’m sure there are more possible applications, but here are the ones from the top of my head.
No comments yet!
Maybe you should write the first one?
likes