Image and Icon are commonly used widgets in Flutter. Image widgets can be used to load and display images. Image data sources can be asset, file, memory, or network. Icon Makes an Icon into a font file and then displays a different picture by specifying different characters. In Android development, the Image Widget is similar to, but more powerful than, ImageView, and can display images directly from the Web. In Android development, this requires the use of third-party libraries or self-implementation.

First, the Image

  const Image({
    Key key,
    @required this.image,
    this.frameBuilder,
    this.loadingBuilder,
    this.semanticLabel,
    this.excludeFromSemantics = false.this.width,
    this.height,
    this.color,
    this.colorBlendMode,
    this.fit,
    this.alignment = Alignment.center,
    this.repeat = ImageRepeat.noRepeat,
    this.centerSlice,
    this.matchTextDirection = false.this.gaplessPlayback = false.this.filterQuality = FilterQuality.low,
  })
Copy the code

Image —- The image to display, of the ImageProvider type

FrameBuilder —- A builder function that creates widgets that represent the image

LoadingBuilder —- a builder that specifies widgets to display to the user while the image is still loading

ExcludeFromSemantics —- whether to exclude images from semantics is useful for images that do not provide meaningful information to the application

Color —- if not null, use [colorBlendMode] to blend this color with each image pixel

ColorBlendMode —- Color mixing mode

Fit —- How do I draw images in allocated space

How do repeat —- draw any part of the layout boundary that is not covered by the image

CenterSlice —-.9 centerSlice of the image

MatchTextDirection —- Whether to draw the image in the direction of [TextDirection]

GaplessPlayback —- Whether to continue displaying old images when the ImageProvider changes (true) or not displaying any images temporarily (false)

FilterQuality —- to set the [filterQuality] of the image

/// The quality level of the image filter
enum FilterQuality {
  // This list comes from Skia's skFilterQuality.h, and the values (order) should be kept in sync.

  /// The fastest filter, albeit of the lowest quality.
  ///
  /// In general, this means adjacent interpolation.
  none,

  /// The quality is better than [none] and faster than [medium].
  ///
  /// In general, this means bilinear interpolation.
  low,

  /// Better quality than [low], faster than [high].
  ///
  /// Often, this means combining bilinear interpolation with pyramidal Parametric Pre-filtering (Mipmap).
  medium,

  /// Best quality filtering, although also slowest.
  ///
  /// Usually, this means bicubic interpolation or better.
  high,
}
Copy the code

1.1 ImageProvider

ImageProvider is an abstract class that mainly defines the interface load() for image data acquisition. Different imageProviders are implemented to obtain images from different data sources. For example AssetImage is an ImageProvider that implements loading images from an Asset, while NetworkImage implements an ImageProvider that loads images from the network.

1.2 Loading images from Asset

1. Create an images folder in the project root directory and copy the image. JPG image to the images folder.

2. Add images to the flutter section of pubspec.yaml.

flutter:
  assets:
    - images/image.jpg
Copy the code

3. Use in code.

Image(image: AssetImage("images/image.jpg"), width: 100.0),
Copy the code

1.3 Loading Images from the Network

Since the frame is already wrapped, we just need to write the image URL to the appropriate location.

/ / method
Image(
  image: NetworkImage(
      "url"),
  width: 100.0.)/ / method 2
Image.network(
  "url",
  width: 100.0.)Copy the code

Here is the sample code to use it.

var imageUrl =
      "https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1583665145895&di=bcb225ca90a68654d2d1699caa9eeaf4&i mgtype=0&src=http%3A%2F%2Fb-ssl.duitang.com%2Fuploads%2Fitem%2F201802%2F20%2F20180220165946_RiGPS.thumb.700_0.jpeg"; . Image(image: NetworkImage(imageUrl), width:100.0),

Image.network(imageUrl,width: 100.0,),
Copy the code

1.4 colorBlendMode

Mixed mode is very many, as for each effect source contains link path, we through the way of the network to load all these pictures come to see.

/// Algorithms to use when painting on a canvas.
enum BlendMode {
  // This list comes from Skia's skxfermode. h, and the values (order) should be kept in sync.
  / / : https://skia.org/user/api/skpaint#SkXfermode
  
  clear,
  src,
  dst,
  srcOver,
  dstOver,
  srcIn,
  dstIn,
  srcOut,
  dstOut,
  srcATop,
  dstATop,
  xor,
  plus,
  modulate,
  screen, 
  overlay,
  darken,
  lighten,
  colorDodge,
  colorBurn,
  hardLight,
  softLight,
  difference,
  exclusion,
  multiply, 
  hue,
  saturation,
  color,
  luminosity,
}
Copy the code

Here is sample code that generates all images according to the rules of the URL.

class ImageBlendModeRoute extends StatelessWidget { @override Widget build(BuildContext context) { var i = 0; var images = <Image>[]; for (i = 0; i < 29; i++) { var modeStr = BlendMode.values[i].toString(); images.add(Image.network( "https://flutter.github.io/assets-for-api-docs/assets/dart-ui/blend_mode_${modeStr.substring(10)}.png", width: 100.0)); } i = 0; return Scaffold( appBar: AppBar( title: Text("ImageBlendModeRoute"), ), body: SingleChildScrollView( child: Column(children: images.map((e) {return Row(children: <Widget>[Padding(Padding: EdgeInsets. All (3.0)), child: SizedBox( width: 100, child: e, ), ), Text( BlendMode.values[i++].toString(), style: TextStyle( fontSize: 15, color: Colors.black, ), ) ], ); }).toList()), )); }}Copy the code

1.5 fit

How to draw images in allocated space has similar properties in Android development.

enum BoxFit {
  fill,
  contain,
  cover,
  fitWidth,
  fitHeight,
  none,
  scaleDown,
}
Copy the code

Fill —- will stretch to fill the display space, the aspect ratio of the picture itself will change, and the picture will be deformed.

Cover —- will zoom in according to the aspect ratio of the image and then center it to fill the display space. The image will not be deformed, and the parts beyond the display space will be cropped.

Contain —- This is the default image adaptation rule, the image will ensure that the image itself length to width ratio is the same to adapt to the current display space, the image will not be distorted.

FitWidth —- The width of the image is scaled to the width of the display space, the height is scaled to scale, and the image is centered. The image does not distort, and the portion of the image outside the display space is clipped.

FitHeight —- The height of the image will be scaled to the height of the display space, the width will be scaled to scale, and then centered, the image will not be distorted, the portion of the image outside the display space will be clipped.

None —- Images have no adaptive policy and will be displayed in the display space. If the image is larger than the display space, only the middle part of the image will be displayed in the display space.

ScaleDown —- aligns the source with the target box (centered by default) and scales down the source if necessary to ensure it fits inside the box.

Take a look at the sample code and you’ll get a good understanding of each of these types when you see them in action.

class ImageFitRoute extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    var img = AssetImage("images/image.jpg");
    return Scaffold(
        appBar: AppBar(
          title: Text("ImageBlendModeRoute"),
        ),
        body: SingleChildScrollView(
          child: Column(
              children: <Image>[
            Image(
              image: img,
              height: 50.0,
              width: 100.0,
              fit: BoxFit.fill,
            ),
            Image(
              image: img,
              height: 50,
              width: 50.0,
              fit: BoxFit.contain,
            ),
            Image(
              image: img,
              width: 100.0,
              height: 50.0,
              fit: BoxFit.cover,
            ),
            Image(
              image: img,
              width: 100.0,
              height: 50.0,
              fit: BoxFit.fitWidth,
            ),
            Image(
              image: img,
              width: 100.0,
              height: 50.0,
              fit: BoxFit.fitHeight,
            ),
            Image(
              image: img,
              width: 100.0,
              height: 50.0,
              fit: BoxFit.scaleDown,
            ),
            Image(
              image: img,
              height: 50.0,
              width: 100.0,
              fit: BoxFit.none,
            ),
          ].map((e) {
            return Row(
              children: <Widget>[
                Padding(
                  padding: EdgeInsets.all(16.0),
                  child: SizedBox(
                    width: 100, child: e, ), ), Text(e.fit.toString()) ], ); }).toList()), )); }}Copy the code

1.6 repeat

Now let’s look at an example that repeats on the X-axis. You can see it right away.

Image(Image: AssetImage("images/image.jpg"), width: 300.0, height: 100.0, repeat: imagerepeat.repeatx,),Copy the code

1.7 filterQuality

To see the interpolation effect, the original image was 100px by 100px, and we fixed the display space to 200 by 200 so that the image would need to be enlarged to fully display. We see that when set to None, the display is poor due to the use of proximity interpolation.

class ImageFilterQualityRoute extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    var img = AssetImage("images/image.jpg");
    return Scaffold(
        appBar: AppBar(
          title: Text("ImageFilterQualityRoute"),
        ),
        body: SingleChildScrollView(
          child: Column(
              children: <Image>[
            Image(
              image: img,
              height: 200.0,
              width: 200.0,
              fit: BoxFit.fill,
              filterQuality: FilterQuality.none,
            ),
            Image(
              image: img,
              height: 200.0,
              width: 200.0,
              fit: BoxFit.fill,
              filterQuality: FilterQuality.low,
            ),
            Image(
              image: img,
              height: 200.0,
              width: 200.0,
              fit: BoxFit.fill,
              filterQuality: FilterQuality.medium,
            ),
            Image(
              image: img,
              height: 200.0,
              width: 200.0,
              fit: BoxFit.fill,
              filterQuality: FilterQuality.high,
            ),
          ].map((e) {
            return Row(
              children: <Widget>[
                Padding(
                  padding: EdgeInsets.all(16.0),
                  child: SizedBox(
                    width: 200, child: e, ), ), Text(e.filterQuality.toString()) ], ); }).toList()), )); }}Copy the code

Second, the Icon

Icon is very simple to use.

  const Icon(
    this.icon, {
    Key key,
    this.size,
    this.color,
    this.semanticLabel,
    this.textDirection,
  }) 
Copy the code

I’ve seen almost all of these properties before. For example, three ICONS are used below.

Icon(Icons.add, color: Colors.red,),
Icon(Icons.pages, color: Colors.red,),
Icon(Icons.face, color: Colors.red,),
Copy the code

2.1 Customize font ICONS

There are many font icon materials on iconfont.cn. We can choose our own ICONS to pack and download. In Flutter, we use TTF format. Please find out how to download this icon.

1. Download the font icon to be used.



2. Copy the downloaded iconfont. TTF file to assets/ Fonts folder.

3. Add TTF in fonts section of pubspec.yaml;

flutter:
  ......
  fonts:
    ......
    - family: customIcon
      fonts:
        - asset: assets/fonts/iconfont.ttf
Copy the code

Use 4.

Dart class and define all the font ICONS we have downloaded. As for the codePoint of IconData, you can see it when you download it from iconfont.cn, as shown in the figure above.

CustomIcons.dart

import 'package:flutter/material.dart';

class CustomIcons {
  static const IconData auto = const IconData(0xe6eb,
      fontFamily: 'customIcon', matchTextDirection: true);

  static const IconData all = const IconData(0xe6ef,
      fontFamily: 'customIcon', matchTextDirection: true);

  static const IconData bussiness_man = const IconData(0xe6f0,
      fontFamily: 'customIcon', matchTextDirection: true);
}
Copy the code

Custom font ICONS are displayed as blue ICONS.

Icon(CustomIcons.auto, color: Colors.blue),
Icon(CustomIcons.all, color: Colors.blue),
Icon(CustomIcons.bussiness_man, color: Colors.blue),
Copy the code



Finally, as usual, attach the full Demo code.

import 'package:flutter/material.dart';

import 'CustomIcons.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo', theme: ThemeData( primarySwatch: Colors.blue, ), home: MyHomePage(), ); }}class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  var imageUrl =
      "https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1583665145895&di=bcb225ca90a68654d2d1699caa9eeaf4&i mgtype=0&src=http%3A%2F%2Fb-ssl.duitang.com%2Fuploads%2Fitem%2F201802%2F20%2F20180220165946_RiGPS.thumb.700_0.jpeg";

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: Text("Home Page"),
        ),
        body: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Row(mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[
              Image(image: AssetImage("images/image.jpg"), width: 100.0),
            ]),
            Row(mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[
              Image(image: NetworkImage(imageUrl), width: 100.0),
            ]),
            Row(mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[
              Image.network(
                imageUrl,
                width: 100.0,
              ),
            ]),
            RaisedButton(
              onPressed: () {
                Navigator.push(context, MaterialPageRoute(builder: (context) {
                  return ImageBlendModeRoute();
                }));
              },
              child: Text("ImageBlendModeRoute"),
            ),
            RaisedButton(
              onPressed: () {
                Navigator.push(context, MaterialPageRoute(builder: (context) {
                  return ImageFitRoute();
                }));
              },
              child: Text("ImageFitRoute"),
            ),
            RaisedButton(
              onPressed: () {
                Navigator.push(context, MaterialPageRoute(builder: (context) {
                  return ImageFilterQualityRoute();
                }));
              },
              child: Text("ImageFilterQualityRoute"),
            ),
            Row(mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[
              Image(
                image: AssetImage("images/image.jpg"),
                width: 300.0,
                height: 100.0, repeat: ImageRepeat.repeatX, ), ]), Row(mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[ Icon( Icons.add, color: Colors.red, ), Icon( Icons.pages, color: Colors.red, ), Icon( Icons.face, color: Colors.red, ), Icon(CustomIcons.auto, color: Colors.blue), Icon(CustomIcons.all, color: Colors.blue), Icon(CustomIcons.bussiness_man, color: Colors.blue), ]), ], )); }}class ImageBlendModeRoute extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    var i = 0;
    var images = <Image>[];
    for (i = 0; i < 29; i++) {
      var modeStr = BlendMode.values[i].toString();
      images.add(Image.network(
        "https://flutter.github.io/assets-for-api-docs/assets/dart-ui/blend_mode_${modeStr.substring(10)}.png",
        width: 100.0)); } i =0;
    return Scaffold(
        appBar: AppBar(
          title: Text("ImageBlendModeRoute"),
        ),
        body: SingleChildScrollView(
          child: Column(
              children: images.map((e) {
            return Row(
              children: <Widget>[
                Padding(
                  padding: EdgeInsets.all(3.0),
                  child: SizedBox(
                    width: 100,
                    child: e,
                  ),
                ),
                Text(
                  BlendMode.values[i++].toString(),
                  style: TextStyle(
                    fontSize: 15, color: Colors.black, ), ) ], ); }).toList()), )); }}class ImageFitRoute extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    var img = AssetImage("images/image.jpg");
    return Scaffold(
        appBar: AppBar(
          title: Text("ImageBlendModeRoute"),
        ),
        body: SingleChildScrollView(
          child: Column(
              children: <Image>[
            Image(
              image: img,
              height: 50.0,
              width: 100.0,
              fit: BoxFit.fill,
            ),
            Image(
              image: img,
              height: 50,
              width: 50.0,
              fit: BoxFit.contain,
            ),
            Image(
              image: img,
              width: 100.0,
              height: 50.0,
              fit: BoxFit.cover,
            ),
            Image(
              image: img,
              width: 100.0,
              height: 50.0,
              fit: BoxFit.fitWidth,
            ),
            Image(
              image: img,
              width: 100.0,
              height: 50.0,
              fit: BoxFit.fitHeight,
            ),
            Image(
              image: img,
              width: 100.0,
              height: 50.0,
              fit: BoxFit.scaleDown,
            ),
            Image(
              image: img,
              height: 50.0,
              width: 100.0,
              fit: BoxFit.none,
            ),
          ].map((e) {
            return Row(
              children: <Widget>[
                Padding(
                  padding: EdgeInsets.all(16.0),
                  child: SizedBox(
                    width: 100, child: e, ), ), Text(e.fit.toString()) ], ); }).toList()), )); }}class ImageFilterQualityRoute extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    var img = AssetImage("images/image.jpg");
    return Scaffold(
        appBar: AppBar(
          title: Text("ImageFilterQualityRoute"),
        ),
        body: SingleChildScrollView(
          child: Column(
              children: <Image>[
            Image(
              image: img,
              height: 200.0,
              width: 200.0,
              fit: BoxFit.fill,
              filterQuality: FilterQuality.none,
            ),
            Image(
              image: img,
              height: 200.0,
              width: 200.0,
              fit: BoxFit.fill,
              filterQuality: FilterQuality.low,
            ),
            Image(
              image: img,
              height: 200.0,
              width: 200.0,
              fit: BoxFit.fill,
              filterQuality: FilterQuality.medium,
            ),
            Image(
              image: img,
              height: 200.0,
              width: 200.0,
              fit: BoxFit.fill,
              filterQuality: FilterQuality.high,
            ),
          ].map((e) {
            return Row(
              children: <Widget>[
                Padding(
                  padding: EdgeInsets.all(16.0),
                  child: SizedBox(
                    width: 200, child: e, ), ), Text(e.filterQuality.toString()) ], ); }).toList()), )); }}Copy the code