[Flutter/Dart] Different view while waiting for image acquisition
- M.R

- Jul 16, 2023
- 2 min read
Things to do
There is a widget that displays an image
Images are acquired from remote storage
Because it takes time, I would like to display notification that it is waiting during that time.
Solution
Switch views in FutureBuilder.
FutureBuilder<ImageProvider>(
future: getImage(),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return CircularProgressIndicator();
}
if ((snapshot.hasError) || (!snapshot.hasData)){
//Error handling
}
return Container(
width: 100,
height: 100,
decoration: BoxDecoration(
borderRadius: const
BorderRadius.all(Radius.circular(10)),
image: DecorationImage(
fit: BoxFit.contain,
image: snapshot.data!
),
)
);
}
)Future<ImageProvider> getImage()async{
//method to get image from remote storage
}Common processing for different image sources
In the above, we considered remote storage as the source of the image, but it can be a local file or an image file in an asset. How can we standardize the processing for these different sources?
Let's create a polymorphic class like this:
Creating an abstract class ImageSource class
Define Future <ImageProvider> getImage()
Define concrete classes LocalImage and RemoteImage that inherit the ImageSource class, and add implementations of getImage for each
The image display widget takes an ImageSource instance as an argument and calls getImage() to get an ImageProvider
abstract class ImageSource{
String path; //image file path
Future<ImageProvider> getImage();
}
//Local image file
class LocalImage extends ImageSource{
@override
Future<ImageProvider> getImage()async{
return FileImage(File(path));
}
}
//Remote storage file
class RemoteImage extends ImageSource{
@override
Future<ImageProvider> getImage()async{
String _downloadPath = await _downLoadFile();
return NetworkImage(_downloadPath);
}
}
Widget ImageWidget(ImageSource imgSrc){
return FutureBuilder<ImageProvider>(
future: imgSrc.getImage(),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return CircularProgressIndicator();
}
if ((snapshot.hasError) || (!snapshot.hasData)){
//Error handling
}
return Container(
width: 100,
height: 100,
decoration: BoxDecoration(
borderRadius: const
BorderRadius.all(Radius.circular(10)),
image: DecorationImage(
fit: BoxFit.contain,
image: snapshot.data!
),
)
);
}
)
}For LocalImage, getImage() doesn't need to be async, but it's async for convenience with RemoteImage.
(Only the image is displayed with almost no waiting)






Comments