Flutter 基础控件篇-->图片(Image)、图标(Icon)

3,630 阅读6分钟

文章已同步至【个人博客】,欢迎访问【我的主页】😃
文章地址:blog.fanjunyang.zone/archives/fl…

Flutter 中,我们可以通过Image组件来加载并显示照片,Image的数据源可以是asset、内存、文件和网络。也可以使用Icon字体图标,来显示不同的图片

Image

可以用来实现加载各种照片。
这里先说一下从asset和网络加载图片的方法,然后说一下相关的属性

源码示例

构造函数如下:

const Image({
	Key key,
	@required this.image,
	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,
})

其中有一个必选的image参数,他对应一个ImageProvider

ImageProvider 是一个抽象类,主要定义了图片数据获取的接口load(),从不同的数据源获取图片需要实现不同的ImageProvider

如AssetImage是实现了从Asset中加载图片的ImageProvider,而NetworkImage实现了从网络加载图片的ImageProvider。

从asset中加载图片

  1. 工程目录(一定是工程目录)下新建一个images文件夹,并将图片logo.jpg拷贝到文件夹下。

  2. pubspec.yaml中的flutter部分添加如下内容:

assets:
   - images/logo.jpg

注: 由于 yaml 文件对缩进要求非常严格,所以必须严格按照每一层两个空格的方式进行缩进,此处assets前面应有两个空格。

  1. 加载该图片
Image(
  image: AssetImage("images/logo.jpg"),	//此处路径要填写上面assets定义的路径
);

Image也提供了一个快捷的构造函数Image.asset用于从asset中加载、显示图片:

Image.asset(
	"images/logo.jpg",
)

从网络加载图片

不需要配置,直接使用

Image(
	//引入网络图片
	image: NetworkImage('https://ss3.bdstatic.com/70cFv8Sh_Q1YnxGkpoWK1HF6hhy/it/u=1785737583,1674337830&fm=26&gp=0.jpg'),
),

Image也提供了一个快捷的构造函数Image.network用于从网络加载、显示图片:

Image.network(
  "https://ss3.bdstatic.com/70cFv8Sh_Q1YnxGkpoWK1HF6hhy/it/u=1785737583,1674337830&fm=26&gp=0.jpg",
)

属性解释

只说一些Image的主要属性

const Image({
  ...
  this.width, //图片的宽
  this.height, //图片高度
  this.color, //图片的混合色值
  this.colorBlendMode, //混合模式
  this.fit,//缩放模式
  this.alignment = Alignment.center, //对齐方式
  this.repeat = ImageRepeat.noRepeat, //重复方式
  ...
})

width、height

用于设置图片的宽、高,当不指定宽高时,图片会根据当前父容器的限制,尽可能的显示其原始大小,
如果只设置widthheight的其中一个,那么另一个属性默认会按比例缩放,但可以通过fit属性来指定适应规则。

fit(重点)

该属性用于在图片的显示空间和图片本身大小不同时指定图片的适应模式。
适应模式是在BoxFit中定义,如:fit: BoxFit.contain

BoxFit 有如下值:

  • fill:会拉伸填充满显示空间,图片本身长宽比会发生变化,图片会变形。
  • cover:会按图片的长宽比放大后居中填满显示空间,图片不会变形,超出显示空间部分会被剪裁。
  • contain:这是图片的默认适应规则,图片会在保证图片本身长宽比不变的情况下缩放以适应当前显示空间,图片不会变形。
  • fitWidth:图片的宽度会缩放到显示空间的宽度,高度会按比例缩放,然后居中显示,图片不会变形,超出显示空间部分会被剪裁。
  • fitHeight:图片的高度会缩放到显示空间的高度,宽度会按比例缩放,然后居中显示,图片不会变形,超出显示空间部分会被剪裁。
  • none:图片没有适应策略,会在显示空间内显示图片,如果图片比显示空间大,则显示空间只会显示图片中间部分。

自己可以尝试写一下试试,这里就不贴图了,因为感觉显示的不太直观,所以还得亲自写一下看看效果

color、colorBlendMode

在图片绘制时可以对每一个像素进行颜色混合处理,
color指定混合色,而colorBlendMode指定混合模式。

代码示例:

Image(
  image: AssetImage("images/logo.jpg"),
  width: 100.0,
  color: Colors.blue,
  colorBlendMode: BlendMode.difference,
);

repeat

当图片本身大小小于显示空间时,指定图片的重复规则。

也就是屏幕大,图片小,用这个属性来设置照片是否平铺,相当于H5中的repeat

代码示例:

Image(
  image: AssetImage("images/logo.jpg"),
  width: 100.0,
  height: 200.0,
  repeat: ImageRepeat.repeatY ,	//设置照片在Y轴平铺
)

其他值:

  • repeat: ImageRepeat.repeatX //设置照片在X轴平铺
  • repeat: ImageRepeat.noRepeat //设置照片不平铺
  • repeat: ImageRepeat.repeat //设置照片在X轴、Y轴平铺

Image缓存

Flutter框架对加载过的图片是有缓存的(内存),默认最大缓存数量是1000,最大缓存空间为100M。

设置圆形图片

这个单独拿出来说一下,有一个组件可以直接设置圆形图片,就是ClipOval

例如:

ClipOval(
 child: Image.network(
   "https://ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=3289458325,1767138375&fm=26&gp=0.jpg",
    width: 100,
 ),
)

他的运行效果直接就是一张圆形图片,当然也可以使用decoration来自定义设置

有关decoration的使用,请移步:Flutter 容器控件篇-->Container

Icon

Flutter中,也可以像Web开发一样使用iconfont,即字体图标,就是将图标做成字体文件,然后通过指定不同的字符而显示不同的图片。
类似于element-ui里面的引用字体图标

在Flutter开发中,iconfont和图片相比有如下优势:

  • 体积小:可以减小安装包大小。
  • 矢量的:iconfont都是矢量图标,放大不会影响其清晰度。
  • 可以应用文本样式:可以像文本一样改变字体图标的颜色、大小对齐等。
  • 可以通过TextSpan和文本混用。

Material Design字体图标

Flutter默认包含了一套Material Design的字体图标,
pubspec.yaml文件中的flutter中配置如下:

flutter:
  uses-material-design: true

Material Design所有图标查看:material.io/resources/i…

使用方法:
Flutter封装了IconDataIcon来专门显示字体图标,Icons类中包含了所有Material Design图标的IconData静态变量定义,

所以使用的时候,我们只需要使用Icons.加图标名就可以了

代码示例:

Row(
  mainAxisAlignment: MainAxisAlignment.center,
  children: <Widget>[
    Icon(Icons.accessible,color: Colors.green,),
    Icon(Icons.error,color: Colors.green,),
    Icon(Icons.fingerprint,color: Colors.green,),
  ],
)

自定义字体图标

我们也可以使用自定义字体图标。iconfont.cn(阿里巴巴的一个矢量图标库)上有很多字体图标素材,我们可以选择自己需要的图标打包下载

下载后,会生成一些不同格式的字体文件,在Flutter中,我们使用ttf格式即可。

假设我们项目中需要使用一个微信图标,

  1. 我们进到网站找到指定图标并打包下载。

  2. 在项目下新建一个文件夹fonts用来存放我们的字体和图标文件(这两者是可以放到一起的),然后将我们下载好的图标文件保存到fonts文件夹下

  3. 接着在pubspec.yaml文件下的flutter中引入

flutter:
  fonts:
    - family: myIcon  #指定一个字体名
      fonts:
        - asset: fonts/iconfont.ttf

一定要注意空格,别多写,也别少写

  1. 为了使用方便,我们定义一个MyIcons类,功能和Icons类一样,将字体文件中的所有图标都定义成静态变量:
class MyIcons{
  // 微信图标
  static const IconData wechat = const IconData(
      0xec7d,  
      fontFamily: 'myIcon', 
      matchTextDirection: true
  );
}
  1. dart文件中使用
Row(
  mainAxisAlignment: MainAxisAlignment.center,
  children: <Widget>[
    Icon(MyIcons.wechat,color: Colors.green,),
  ],
)
  1. 运行,完美

H_H