欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Flutter Widgets: Image

程序员文章站 2022-03-11 10:52:40
...

介绍

Image, 图片显示Widget, 和Android ImageView相似,但是从实际使用的方法上看,与常用的图片加载库,如Picasso,Glide等相似,支持本地图片,资源图片,网络图片等加载方式。

类结构

Flutter Widgets: Image

构造方法

方式 解释
Image() 通用方法,使用ImageProvider实现,如下方法本质上也是使用的这个方法
Image.asset 加载资源图片
Image.file 加载本地图片文件
Image.network 加载网络图片
Image.memory 加载Uint8List资源图片

属性值

image

ImageProvider, 抽象类,需要自己实现获取图片数据的操作。如下是常用的一些ImageProvider,当然自定义自己的ImageProvider也是OK的,实现方法,可以参考下面表中这些已经成熟使用的例子。

ImageProvider
ExactAssetImage
AssetImage
NetworkImage
FileImage
MemoryImage
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return new Scaffold(
      appBar: new AppBar(title: new Text("Container Test"),
        centerTitle: true,),

      body: new ListView(
        children: <Widget>[
          // 资源图片
          new Image.asset('imgs/logo.jpeg'),
          //网络图片
          new Image.network(
              'https://flutter.io/images/homepage/header-illustration.png'),
          // 本地文件图片
          new Image.file(new File("/Users/gs/Downloads/1.jpeg")),
          // Uint8List图片
          new Image.memory(bytes),
          //使用ImageProvider加载图片
          new Image(image: new NetworkImage(
              "https://flutter.io/images/homepage/screenshot-2.png"),)
        ],
      ),
    );
  }

Flutter Widgets: Image

width & height

Image显示区域的宽度和高度设置,这里需要把Image和图片两个东西区分开,图片本身有大小,Image Widget本身也是有大小的,Image Widget是图片的容器。宽度和高度的配置经常和下面的fit属性配合使用。

  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    Image image = new Image.asset(
      'imgs/logo.jpeg',
      width: 200.0,
      height: 100.0,
      fit: BoxFit.fill,
    );

    return new Scaffold(
      appBar: new AppBar(title: new Text("Image Test"),
        centerTitle: true,),
      body: image,
    );
  }

设置宽度高度,然后设置图片充满Image,因为我们的源图片是1:1的大小,所以这里拉伸或者挤压是正常。
Flutter Widgets: Image

fit

fit Description Result
BoxFit.fill 全图显示,显示可能拉伸,充满 Flutter Widgets: Image
BoxFit.contain 全图显示,显示原比例,不需充满 Flutter Widgets: Image
BoxFit.cover 显示可能拉伸,可能裁剪,充满 Flutter Widgets: Image
BoxFit.fitWidth 显示可能拉伸,可能裁剪,宽度充满 Flutter Widgets: Image
BoxFit.fitHeight 显示可能拉伸,可能裁剪,高度充满 Flutter Widgets: Image
BoxFit.none
BoxFit.scaleDown 效果和contain差不多,但是此属性不允许显示超过源图片大小,可小不可大 Flutter Widgets: Image

color & colorBlendMode

color和colorBlendMode一般配合使用,BlendMode, 为混合模式的意思,包含如下诸多模式。感觉和Android中Xfermode是一个原理。
Flutter Widgets: Image
随意看几个效果吧。

BlendMode.colorBurn

    Image image = new Image.asset(
      'imgs/logo.jpeg',
      width: 400.0,
      height: 500.0,
      fit: BoxFit.scaleDown,
      color: Colors.greenAccent,
      colorBlendMode: BlendMode.colorBurn,
    );

Flutter Widgets: Image

BlendMode.exclusion

Flutter Widgets: Image

BlendMode.colorDodge

Flutter Widgets: Image

alignment

控制图片的摆放位置。如下将图片放置在右下角。其他的位置自行尝试。

alignment: Alignment.bottomRight,

Flutter Widgets: Image

repeat

一图胜前言

    Image image = new Image.asset(
      'imgs/logo.jpeg',
      width: 400.0,
      height: 500.0,
      fit: BoxFit.scaleDown,
      repeat: ImageRepeat.repeat,
    );
repeat Results
ImageRepeat.repeat Flutter Widgets: Image
ImageRepeat.repeatX Flutter Widgets: Image
ImageRepeat.repeatY Flutter Widgets: Image
ImageRepeat.none Flutter Widgets: Image

centerSlice

当图片需要被拉伸显示的时候,centerSlice定义的矩形区域会被拉伸,可以理解成我们在图片内部定义来一个点9文件用作拉伸。

    Image image = new Image.asset(
      'imgs/logo.jpeg',
      width: 500.0,
      height: 500.0,
      fit: BoxFit.contain,
      centerSlice: new Rect.fromCircle(center: const Offset(100.0, 100.0), radius: 10.0 ),
    );

Flutter Widgets: Image
注意一下这部分,代码中有如是一段:

assert(sourceSize == inputSize, 'centerSlice was used with a BoxFit that does not guarantee that the image is fully visible.');

也就是说只有在显示大小大于原图大小的情况下,才允许使用这个属性,否则会报错。

matchTextDirection

与Directionality配合使用

  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    Image image = new Image.asset(
      'imgs/android.jpg',
      fit: BoxFit.scaleDown,
      matchTextDirection: true,
    );
    return new Scaffold(
        appBar: new AppBar(title: new Text("Image Test"),
          centerTitle: true,),
        body: new ListView(

          children: <Widget>[
            new Directionality(
              textDirection: TextDirection.ltr,
              child: image,
            ),
            new Directionality(
              textDirection: TextDirection.rtl,
              child: image,
            ),
          ],
        )
    );
  }

列表中两个图片,第一个是TextDirection.ltr,第二个TextDirection.rtl。
Flutter Widgets: Image

gaplessPlayback

当ImageProvider发生变化后,重新加载图片的过程中,原图片的展示是否保留。若值为true,保留,若为false,不保留,直接空白等待下一张图片加载。

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;
  NetworkImage networkImage = new NetworkImage("https://flutter.io/images/homepage/header-illustration.png");

  @override
  _MyHomePageState createState() => new _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {

  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return new Scaffold(
        appBar: new AppBar(title: new Text("Image Test"),
          centerTitle: true,),
        body: new ListView(
          children: <Widget>[
            new Directionality(
              textDirection: TextDirection.ltr,
              child: new Image(image: widget.networkImage, fit: BoxFit.contain,gaplessPlayback: true,),
            ),
            new InkWell(
              child: new Text("点击我切换图片", textAlign: TextAlign.center,),
              onTap: (){
                setState(() {
                  print("change pic");
                  widget.networkImage = new NetworkImage("https://flutter.io/images/intellij/hot-reload.gif");
                });
              },)
          ],
        )
    );
  }
}
gaplessPlayback Result
true Flutter Widgets: Image
false Flutter Widgets: Image