Flutter 基础组件之 Image

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/zgcqflqinhao/article/details/85068055

正所谓一图胜千言,一张意思清晰明了的图片胜过 N 句废话,所以图片的展示是相当重要的,Image 是 Flutter 用于展示图片的控件,它可以加载项目内的图片、手机存储中的图片以及直接从网络加载图片,不用再集成图片加载框架就可以加载网络图片这就很方便了。

1 构造方法

Image({Key key, @required ImageProvider image, String semanticLabel, bool excludeFromSemantics: false, double width, double height, Color color, BlendMode colorBlendMode, BoxFit fit, AlignmentGeometry alignment: Alignment.center, ImageRepeat repeat: ImageRepeat.noRepeat, Rect centerSlice, bool matchTextDirection: false, bool gaplessPlayback: false, FilterQuality filterQuality: FilterQuality.low })

创建一个 Image 组件,其中一个必传参数为 ImageProvider,它指定了图片是从哪里加载,是从项目中还是网络中等等。 

Image.asset(String name, { Key key, AssetBundle bundle, String semanticLabel, bool excludeFromSemantics: false, double scale, double width, double height, Color color, BlendMode colorBlendMode, BoxFit fit, AlignmentGeometry alignment: Alignment.center, ImageRepeat repeat: ImageRepeat.noRepeat, Rect centerSlice, bool matchTextDirection: false, bool gaplessPlayback: false, String package, FilterQuality filterQuality: FilterQuality.low })

创建一个从项目中的资源目录加载图片的 Image,其实就相当于第一种构造方法指定 ImageProvider 为 AssetImage。

Image.file(File file, { Key key, double scale: 1.0, String semanticLabel, bool excludeFromSemantics: false, double width, double height, Color color, BlendMode colorBlendMode, BoxFit fit, AlignmentGeometry alignment: Alignment.center, ImageRepeat repeat: ImageRepeat.noRepeat, Rect centerSlice, bool matchTextDirection: false, bool gaplessPlayback: false, FilterQuality filterQuality: FilterQuality.low })

创建一个从手机存储目录加载图片的 Image,其实就相当于第一种构造方法指定 ImageProvider 为 FlieImage。

Image.memory(Uint8List bytes, { Key key, double scale: 1.0, String semanticLabel, bool excludeFromSemantics: false, double width, double height, Color color, BlendMode colorBlendMode, BoxFit fit, AlignmentGeometry alignment: Alignment.center, ImageRepeat repeat: ImageRepeat.noRepeat, Rect centerSlice, bool matchTextDirection: false, bool gaplessPlayback: false, FilterQuality filterQuality: FilterQuality.low })

应该是创建一个从内存或者字节流加载图片的 Image,其实就相当于第一种构造方法指定 ImageProvider 为 MemoryImage。

Image.network(String src, { Key key, double scale: 1.0, String semanticLabel, bool excludeFromSemantics: false, double width, double height, Color color, BlendMode colorBlendMode, BoxFit fit, AlignmentGeometry alignment: Alignment.center, ImageRepeat repeat: ImageRepeat.noRepeat, Rect centerSlice, bool matchTextDirection: false, bool gaplessPlayback: false, FilterQuality filterQuality: FilterQuality.low, Map<String, String> headers })

创建一个从网络加载图片的 Image,其实就相当于第一种构造方法指定 ImageProvider 为 NetworkImage。

其实后四种构造方法就相当于对第一种构造方法进行了封装,不用传入 ImageProvider 而已,但是仍要传入图片路径,所以说也没省多大事,我比较倾向用第一种构造方法。

2 常用属性

image:从哪里加载图片,值为一个 ImageProvider 对象,ImageProvider 的实现类有 AssetBundleImageProvider(AssetImage 继承自它)、FileImage、MemoryImage、NetworkImage,需要注意的是,如果选择 AssetImage 从资源目录中加载图片,需在 pubspec.yaml 配置文件中配置 assets 目录:

必须是上面的层级关系,但是感觉从资源目录加载图片老有问题,有时候显示不出来但又不报错,可以试试目录后面跟上具体文件名,即:

但是这样每张图片都得配置,未免太过麻烦,而选择 NetworkImage 从网络加载图片就简单多了,只需要指定图片的 url 即可。

width heigh:宽和高,不必赘述。

alignment:如果图片没有填充满容器的话,图片的对齐方式,值为一个 AlignmentGeometry 对象,Alignment 是它的一个实现类,可选值同 Container 的 Alignment 取值一样。
    Alignment.topLeft:垂直靠顶部水平靠左对齐。
    Alignment.topCenter:垂直靠顶部水平居中对齐。
    Alignment.topRight:垂直靠顶部水平靠右对齐。
    Alignment.centerLeft:垂直居中水平靠左对齐。
    Alignment.center:垂直和水平居中都对齐。
    Alignment.centerRight:垂直居中水平靠右对齐。
    Alignment.bottomLeft:垂直靠底部水平靠左对齐。
    Alignment.bottomCenter:垂直靠底部水平居中对齐。
    Alignment.bottomRight:垂直靠底部水平靠右对齐。
    除了上面的常量之外,还可以创建 Alignment 对象指定 x、y 偏移量。

color:在图片上设置颜色,值为一个 Color 对象,会覆盖 image 指定的图片,如果也设置了 colorBlendMode 属性,则会与 image 混合产生特殊效果。

colorBlendMode:颜色混合模式,类似 BoxDecoration 的 backgroundBlendMode。

excludeFromSemantics:是否启用图像的语义描述。

filterQuality:图像过滤器的质量级别(使用该属性还没看到效果,后面用到了再研究)。

fit:图片的缩放方式,类似 Android 中 ImageView 的 scaleType,可选值有:
    BoxFit.none:将图片的内容按原大小居中显示。
    BoxFit.contain:将图片的内容完整居中显示,通过按比例缩小或原来的 size 使得图片宽/高等于或小于组件的宽/高,类似 Android 的 centerInside。
    BoxFit.cover:按比例放大图片的 size 居中显示,类似 Android 的 centerCrop。
    BoxFit.fill:把图片不按比例放大/缩小到组件的大小显示,类似 Android 的 fitXY。
    BoxFit.fitHeight:把图片的高按照组件的高显示,宽等比例放大/缩小。
    BoxFit.fitWidth:把图片的宽按照组件的宽显示,高等比例放大/缩小。
    BoxFit.scaleDown:如果图片宽高大于组件宽高,则让图片内容完全居中显示,此时同 contain,如果图片宽高小于组件宽高,则按图片原大小居中显示,此时同 none。

centerSlice:该属性用于 .9 图的中心拉伸,值为一个 Rect 对象,应该就是拉伸区域,我在使用该属性的时候只有当 fit 设置为 contain 和 fill 时才看到了效果,该属性应该也是用于图形变换,不常用。

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

matchTextDirection:该属性值表示图片的方向是否跟随文字的方向,其实就相当于左右翻转,true 表示翻转,false 表示不翻转,但是要想该属性生效,必须使用 Directionality 组件包裹 Image 组件,如下面代码:

new Directionality(
    textDirection: TextDirection.rtl,
    child: new Image(
        image: new NetworkImage(imgUrl),
        matchTextDirection: true,
    ),
)

上面代码中的 textDirection 属性值为 TextDirection.rtl,即从右向左,然后 Image 组件的图片方向跟随文字方向也是从右向左,即相当于左右翻转的效果。

repeat:如果图片没填充满容器的话,图片的重复方式,可选值有:
    ImageRepeat.noRepeat:不重复。
    ImageRepeat.repeat:X、Y 轴都重复。
    ImageRepeat.repeatX:只在 X 轴重复。
    ImageRepeat.repeatY:只在 Y 轴重复。

semanticLabel:图像的语义描述,类似 Android 中 ImageView 的 contentDescription 属性。

下面是一个设置了上面部分属性的 Image 组件的 demo:

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
//    var imgUrl =
//        "https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1545191828292&di=caef0d773e90142191de9fc5f5871cef&imgtype=0&src=http%3A%2F%2Fimg.mp.sohu.com%2Fq_mini%2Cc_zoom%2Cw_640%2Fupload%2F20170807%2Fb008bbf3df1b490d85e3ff3152ea898e_th.jpg";
    var imgUrl =
        "https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1545790666&di=45beff1e706ea81d796d2268553c9e6f&imgtype=jpg&er=1&src=http%3A%2F%2Fp1.music.126.net%2FfydScGuKzV4GFdqeCMKhxQ%3D%3D%2F109951163178133629.jpg%3Fparam%3D180y180";
    return MaterialApp(
      //是否显示 debug 标签
      debugShowCheckedModeBanner: false,
      title: "Image",
      home: Scaffold(
        appBar: new AppBar(
          title: new Text("Image"),
        ),
        body: new Container(
          color: new Color(0xFFFF0000),
          //子组件
          child: new Image(
            //从资源目录中加载图片,需在 pubspec.yaml 配置文件中配置 assets 目录
            //flutter:
            //  assets:
            //    - assets/images/
            //必须是上面的层级关系,但是感觉从资源目录加载图片老有问题,有时候显示不出来但又不报错,可以试试目录后面跟上具体文件名,即
            //flutter:
            //  assets:
            //    - assets/images/iverson.jpg
            //但是这样每张图片都得配置,未免太过麻烦
//            image: new AssetImage("assets/images/iverson.jpg"),
            //从网络加载图片,非常容易,不用配置,而且只要有网就没什么问题
            image: new NetworkImage(imgUrl),
            width: 300,
            height: 200,
            //如果图片没有填充满容器的话,图片的对齐方式,值为一个 AlignmentGeometry 对象,Alignment 是它的一个实现类
            //可选值同 Container 的 Alignment 取值一样。
            //Alignment.topLeft:垂直靠顶部水平靠左对齐
            //Alignment.topCenter:垂直靠顶部水平居中对齐
            //Alignment.topRight:垂直靠顶部水平靠右对齐
            //Alignment.centerLeft:垂直居中水平靠左对齐
            //Alignment.center:垂直和水平居中都对齐
            //Alignment.centerRight:垂直居中水平靠右对齐
            //Alignment.bottomLeft:垂直靠底部水平靠左对齐
            //Alignment.bottomCenter:垂直靠底部水平居中对齐
            //Alignment.bottomRight:垂直靠底部水平靠右对齐
            //除了上面的常量之外,还可以创建 Alignment 对象指定 x、y 偏移量
            alignment: Alignment.center,
            //在图片上设置颜色,值为一个 Color 对象,会覆盖 image 指定的图片,如果也设置了 colorBlendMode 属性,则会与 image 混合产生特殊效果
            color: new Color(0xFFFFFF00),
            //颜色混合模式,类似 BoxDecoration 的 backgroundBlendMode
            colorBlendMode: BlendMode.darken,
//            excludeFromSemantics: true,
//            filterQuality: FilterQuality.high,
            //图片的缩放方式,类似 Android 中 ImageView 的 scaleType,可选值有:
            //BoxFit.none:将图片的内容按原大小居中显示。
            //BoxFit.contain:将图片的内容完整居中显示,通过按比例缩小或原来的 size 使得图片宽/高等于或小于组件的宽/高,类似 Android 的 centerInside。
            //BoxFit.cover:按比例放大图片的 size 居中显示,类似 Android 的 centerCrop。
            //BoxFit.fill:把图片不按比例放大/缩小到组件的大小显示,类似 Android 的 fitXY。
            //BoxFit.fitHeight:把图片的高按照组件的高显示,宽等比例放大/缩小。
            //BoxFit.fitWidth:把图片的宽按照组件的宽显示,高等比例放大/缩小。
            //BoxFit.scaleDown:如果图片宽高大于组件宽高,则让图片内容完全居中显示,此时同 contain,如果图片宽高小于组件宽高,则按图片原大小居中显示,此时同 none。
            fit: BoxFit.contain,
//            centerSlice:new Rect.fromCircle(center: Offset(100.0, 100.0), radius: 10.0),
//            gaplessPlayback: true,
            matchTextDirection: true,
            //如果图片没填充满容器的话,图片的重复方式,可选值有:
            //ImageRepeat.noRepeat:不重复
            //ImageRepeat.repeat:X、Y 轴都重复
            //ImageRepeat.repeatX:只在 X 轴重复
            //ImageRepeat.repeatY:只在 Y 轴重复
            repeat: ImageRepeat.noRepeat,
//            semanticLabel: "",
          ),
        ),
      ),
    );
  }
}

运行效果如下:

3 总结

Flutter 加载网络图片比起 Android 要略微简单一些,不过要是加载项目包中的图片可能还需要一些配置,这个可以是利弊皆有,最常用的 Text 和 Image 组件看过后发现其实并不难,还有什么理由不继续,加油少年。

猜你喜欢

转载自blog.csdn.net/zgcqflqinhao/article/details/85068055