[Flutter/Dart] Different view while waiting for image acquisition
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)
Recent Posts
See AllWhat want to do I want to create an input form using TextField. For example, if the input content is a monetary amount, I would like to...
What want to do There is a variable that remain unchanged once the initial value is determined. However, it cannot be determined yet when...
What want to do As the title suggests. Place two widgets in one line on the screen One in the center of the screen and the other on the...
Comments