Introduction of implementation pattern with size of image you want to display of FittedBox widget on Flutter
Introduction
It may seem trivial, but it’s very important. Especially for UI. This is a story about how the image display using the FittedBox widget changes when the image size changes. Consider that you have an admin app and a user app, and you want to upload an image from the admin app and display that image in the user app. And consider the case where the size of the image is not limited at all in the admin application. You are developing a user app, how will you use the FittedBox widget? During implementation, do not be relieved just because the test images are displayed correctly. This is because you don’t know what size images will be uploaded in production. So I decided to find BoxFit, a FittedBox widget that can display any image correctly.
Experiment started
There are 18 patterns for displaying an image, depending on the shape and size of the image and its parent widget. First, I need to sort out the pattern.
18 patterns that can occur in the relationship between the parent widget and the image to be displayed
Parent widgets are vertical, horizontal, or square
The image I want to display is portrait, landscape, or square
The image to be displayed is larger or smaller than the size of the parent widget
Next, I searched for a BoxFit that could correctly display these 18 patterns among fitWidth, fitHeight, contain, cover, fill, scaleDown, and none. I defined NG as shown below, and derived a BoxFit that can handle 18 patterns of the parent widget and the shape and size of the image I want to display.
NG Definition
The size of the widget will be larger than the size of the parent widget
The angle of view of the displayed image is broken
The base source code used for the experiment
Container( -------------- 1
color: Colors.yellow,
width: 300, -------------- 2
height: 100, -------------- 3
child: FittedBox(
fit: BoxFit.contain, -------------- 4
child: Image.network('url')),----------- 5
),
1. Parent widget
2. Parent widget width
3. Parent widget height
4. BoxFit
5. The image I want to display
I experimented with 18 patterns and combinations of BoxFit while changing 2, 3, 4, and 5.
Conclusion
The following correctly displayed all 18 patterns.
BoxFit.contain
Proof of Conclusion
Let’s take a look at how the 18 patterns are displayed using BoxFit.contain.
1. If the parent widget is tall, and the image I want to display is tall, wide, or square, and is larger than the parent widget
Source code used in the experiment
Container(
color: Colors.yellow,
width: 100,
height: 300,
child: FittedBox(
fit: BoxFit.contain,
child: Image.network('url')),
),
The image sizes I want to display are from left to right: 267 x 400, 400 x 172, 400 x 400
All images are contained inside the parent widget.
2. If the parent widget is horizontal and the image I want to display is vertical, horizontal, or square, and is larger than the parent widget
Source code used in the experiment
Container(
color: Colors.yellow,
width: 300,
height: 100,
child: FittedBox(
fit: BoxFit.contain,
child: Image.network('url')),
),
The image sizes I want to display are from left to right: 267 x 400, 400 x 172, 400 x 400
All images are contained inside the parent widget.
3. If the parent widget is a square, and the image I want to display is vertical, horizontal, or square, and is larger than the parent widget
Source code used in the experiment
Container(
color: Colors.yellow,
width: 300,
height: 300,
child: FittedBox(
fit: BoxFit.contain,
child: Image.network('url')),
),
The image sizes I want to display are from left to right: 267 x 400, 400 x 172, 400 x 400
All images are contained inside the parent widget.
4. If the parent widget is tall, and the image I want to display is tall, wide, or square, and is smaller than the parent widget
Source code used in the experiment
Container(
color: Colors.yellow,
width: 100,
height: 300,
child: FittedBox(
fit: BoxFit.contain,
child: Image.network('url')),
),
The image sizes I want to display are from left to right: 34 x 50, 50 x 22, 50 x 50
It’s blurry, but all the images fit inside the parent widget.
5. If the parent widget is horizontal and the image I want to display is vertical, horizontal, or square, and smaller than the parent widget
Source code used in the experiment
Container(
color: Colors.yellow,
width: 300,
height: 100,
child: FittedBox(
fit: BoxFit.contain,
child: Image.network('url')),
),
The image sizes I want to display are from left to right: 34 x 50, 50 x 22, 50 x 50
It’s blurry, but all the images fit inside the parent widget.
6. If the parent widget is a square, and the image I want to display is vertical, horizontal, or square, and is smaller than the parent widget
Source code used in the experiment
Container(
color: Colors.yellow,
width: 300,
height: 300,
child: FittedBox(
fit: BoxFit.contain,
child: Image.network('url')),
),
The image sizes I want to display are from left to right: 34 x 50, 50 x 22, 50 x 50
It’s blurry, but all the images fit inside the parent widget.
Let’s take a look at some of the things that went wrong
NG example of fitWidth
If the parent widget is horizontal and the image I want to display is vertical, horizontal, or square, and is larger than the parent widget
Source code used in the experiment
Container(
color: Colors.yellow,
width: 300,
height: 100,
child: FittedBox(
fit: BoxFit.fitWidth,
child: Image.network('url')),
),
The image sizes I want to display are from left to right: 267 x 400, 400 x 172, 400 x 400
A vertical, square image will be displayed overhanging the parent widget.
NG example of fitHeight
If the parent widget is tall, and the image I want to display is tall, wide, or square, and is larger than the parent widget
Source code used in the experiment
Container(
color: Colors.yellow,
width: 100,
height: 300,
child: FittedBox(
fit: BoxFit.fitHeight,
child: Image.network('url')),
),
The image sizes I want to display are from left to right: 267 x 400, 400 x 172, 400 x 400
A horizontal or square image will be displayed overhanging the parent widget.
NG example of cover
If the parent widget is tall, and the image I want to display is tall, wide, or square, and is larger than the parent widget
Source code used in the experiment
Container(
color: Colors.yellow,
width: 100,
height: 300,
child: FittedBox(
fit: BoxFit.cover,
child: Image.network('url')),
),
The image sizes I want to display are from left to right: 267 x 400, 400 x 172, 400 x 400
A horizontal or square image will be displayed overhanging the parent widget.
NG example of fill
If the parent widget is tall, and the image I want to display is tall, wide, or square, and is larger than the parent widget
Source code used in the experiment
Container(
color: Colors.yellow,
width: 100,
height: 300,
child: FittedBox(
fit: BoxFit.fill,
child: Image.network('url')),
),
The image sizes I want to display are from left to right: 267 x 400, 400 x 172, 400 x 400
The image will be stretched.
NG example of scaleDown
If the parent widget is a square, and the image I want to display is vertical, horizontal, or square, and is smaller than the parent widget
Source code used in the experiment
Container(
color: Colors.yellow,
width: 100,
height: 100,
child: FittedBox(
fit: BoxFit.scaleDown,
child: Image.network('url')),
),
The image sizes I want to display are from left to right: 34 x 50, 50 x 22, 50 x 50
It is better to be stretched to the size of the parent widget as in contain.
NG example of none
If the parent widget is tall, and the image I want to display is tall, wide, or square, and is larger than the parent widget
Source code used in the experiment
Container(
color: Colors.yellow,
width: 100,
height: 300,
child: FittedBox(
fit: BoxFit.none,
child: Image.network('url')),
),
The image sizes I want to display are from left to right: 267 x 400, 400 x 172, 400 x 400
Not at all.
Summary
If you cannot assume the size of the image, it turns out that using BoxFit.contain is the right answer. If you can take advantage of this result, you can eliminate anxiety and experiment time. By the way, if you use cached_network_image, you won’t have to worry about the UI collapsing because the image extends beyond the parent widget.