Preface:
This is the 10th day of my participation in the August More text Challenge. For details, see: August More Text Challenge. To prepare for the August challenge of the nuggets, I’m going to pick 31 components this month that haven’t been introduced before and do a full analysis and attribute introduction. These articles will be used as important material in the collection of the Flutter components. I hope I can stick to it, your support will be my biggest motivation ~
This series | Component articles | The list of |
---|---|---|
1.NotificationListener | 2.Dismissible | 3.Switch |
4.Scrollbar | 5.ClipPath | 6.CupertinoActivityIndicator |
7.Opacity | 8.FadeTransition | 9. AnimatedOpacity |
10. FadeInImage[this article] |
1. Understand the FadeInImage component
As we all know, no matter whether an image is loaded from a resource, a file, or a network, it will not be completed immediately, and there will be a short blank space, especially for web images. Processing the default placeholder map is also more troublesome. The function of FadeInImage is: in the target image load before using the default image placeholder, loading is complete, the target image will fade in, the default image will fade out, so you can both solve the image load placeholder problem, the gradient animation in the visual is not obvious. In this article, I’ll take a comprehensive look at the use of the FadeInImage component and a simple source code implementation.
1. Basic information about FadeInImage
First, it’s a StatelessWidget, which means that it doesn’t maintain a complex state class itself, but is only responsible for building components in the build method.
In a normal construct, you must pass in two ImageProvider objects, image representing the target image resource to be loaded, and placeholder representing the placeholder image resource to be displayed while the target image is loaded. There are also a number of properties for configuring images and animations, which I’ll cover later.
final ImageProvider placeholder;
final ImageProvider image;
Copy the code
2. Simple use of FadeInImage
Using FadeInImage is easiest when you know the two image resources, and you can limit the size of the image by width and height. The image below is a web image, the black is a placeholder, and the effect is as follows:
The property name | type | The default value | use |
---|---|---|---|
placeholder | ImageProvider | required | Placeholder image resources |
image | ImageProvider | required | Target Image Resources |
width | double | null | Image width |
height | double | null | Pictures of high |
class FadeInImageDemo extends StatelessWidget{
final headUrl =
'https://sf1-ttcdn-tos.pstatp.com/img/user-avatar/5b2b7b85d1c818fa71d9e2e8ba944a44~300x300.image';
@override
Widget build(BuildContext context) {
return FadeInImage(
width: 100,
height: 100,
placeholder: AssetImage(
'assets/images/default_icon.png', ), image: NetworkImage(headUrl), ); }}Copy the code
3.FadeInImage animation configuration
FadeOut is for placeholder maps and fadeIn is for target maps. We can configure the duration and curve of two animations to achieve the desired animation effect. Here is the effect of the test case:
The property name | type | The default value | use |
---|---|---|---|
fadeOutDuration | Duration | 300 ms | Placeholder map fade out time |
fadeOutCurve | Curves | Curves.easeOut | Placeholders fade animation curves |
fadeInDuration | Duration | 700 ms | Fade in time of target graph |
fadeInCurve | Curves | Curves.easeIn | Fade the target image into the animation curve |
FadeInImage(
width: 100,
height: 100,
fadeOutDuration:Duration(seconds: 1),
fadeOutCurve: Curves.easeOutQuad,
fadeInDuration: Duration(seconds: 2),
fadeInCurve: Curves.easeInQuad,
placeholder: AssetImage(
'assets/images/default_icon.png',
),
image: NetworkImage(headUrl),
);
Copy the code
4.FadeInImage error builder
These two XXxErrorBuilders are designed to handle how images should be displayed if they load incorrectly. If not, it will look something like this:
We can specify the XXXErrorBuilder callback to build the component that will be displayed in case of an error. As shown in the following example, when a placeholder error occurs, a blue Container is displayed. You can specify any Widget.
The property name | type | The default value | use |
---|---|---|---|
placeholderErrorBuilder | ImageErrorWidgetBuilder | null | Placeholder map loading error when builder |
imageErrorBuilder | ImageErrorWidgetBuilder | null | Target graph loading error when builder |
class FadeInImageDemo extends StatelessWidget{
final headUrl =
'https://sf1-ttcdn-tos.pstatp.com/img/user-avatar/5b2b7b85d1c818fa71d9e2e8ba944a44~300x300.image';
@override
Widget build(BuildContext context) {
return
FadeInImage(
width: 100,
height: 100,
fadeOutDuration:Duration(seconds: 1),
fadeOutCurve: Curves.easeOutQuad,
fadeInDuration: Duration(seconds: 2),
fadeInCurve: Curves.easeInQuad,
placeholderErrorBuilder: _placeholderErrorBuilder,
placeholder: AssetImage(
'assets/images/default_icon2.png',
),
image: NetworkImage(headUrl),
);
}
Widget _placeholderErrorBuilder(BuildContext context, Object error, StackTrace? stackTrace) {
return Container(
width: 100,
height: 100, color: Colors.blue, ); }}Copy the code
5.FadeInImage Other attributes
The rest of the properties are passed to the Image, which means they are the same as the properties in the Image, so I won’t expand them out here.
6. Other constructs for FadeInImage
In addition to normal constructs, FadeInImage also has assetNetwork and memoryNetwork, which are just the difference between the placeholder component being an asset path or Uint8List byte array. These two constructs are designed for ease of use and can specify scaling as well as width and height.
You can see that the two ImageProvider member objects are processed through the ResizeImage, which allows you to change the size of the image resource, usually to reduce the memory footprint of the ImageCache.
That concludes the use of FadeInImage. Let’s look at how FadeInImage, as a StatelessWidget, can perform such complex component content changes.
Two, FadeInImage component source implementation
1. Build the FadeInImage component
For StatelessWidgets, the logic is basically just about how to build the component in the Build method. Here is FadeInImage#build, which creates the result component with the _image method, and a frameBuilder build callback that uses the _AnimatedFadeOutFadeIn component.
If excludeFromSemantics=false then you put in a semantic component, Semantics. That’s what the FadeInImage construct is all about.
The _image method just builds the Image component based on the input parameters and member attributes, nothing special. Now the core is the frameBuilder callback that builds _AnimatedFadeOutFadeIn. So when is Image#frameBuilder called? Let the bullets fly for a while, now take a look at the implementation of _AnimatedFadeOutFadeIn.
2. _AnimatedFadeOutFadeIn
Component implementation
It inherits from ImplicitlyAnimatedWidget, which means it is an implicit animation component. As described in the article AnimatedOpacity, an implicit component can trigger an animation just by changing the configuration properties of the outside world and reconstructing the component without manipulating the animation controller.
In _AnimatedFadeOutFadeInState # build, you can see that fades animation implementation is done by two FadeTransition, both through the Stack composite. It looks like the light is on the horizon.
3. How to trigger the gradient animation
As stated in AnimatedOpacity, for an implicit component, the animation is started by changing properties and reconstructing the component to trigger the State#didUpdateWidget to start the animation.
The question is how to refactor _AnimatedFadeOutFadeIn for FadeInImage, which is a StatelessWidget. Now is a good time to look at frameBuilder. The Image component’s frameBuilder is a callback build that is triggered when _ImageState is built.
The first time the image is not loaded:
The second time is when the image is loaded:
Attribute change + component refactoring to trigger the animation start of implicit components to complete requirements. You can see that FadeInImage is very clever. Thanks for watching, see you tomorrow ~