flutter-widget-image

896 阅读3分钟

在flutter中的image主要有以下几种: AssetImage、DecorationImage、ExactAssetImage、FadeInImage、FileImage、NetworkImage、RawImage、MemoryImage,Image。

AssetImage:从AssetBundle中获取图像,根据上下文来确定使用确切的图像。根据给定的一些资源,AssetImage 可以根据你给定的配置,然后根据设备的像素比率和大小,然后选择合适的资源文件。

使用

以'Nx'的形式命名图片资源文件,其中N标识改资源文件的标称设备像素比率

假如某一个应用程序使用命名为 heart.png 的图标,此图标的表示为1.0(主图标),以及 1.5和2.0像素比。然后我们在资源包中应如下命名:

heart.png

1.5x/heart.png

2.0x/heart.png

在具有1.0设备像素比的设备上,所选择的图片是 heart.png ,在具有1.3设备的像素比的设备上,所选择图片是 1.5x/heart.png. 只要变量命名处于同一个目录层级,资源文件的目录层级就无关紧要。如下也是有效的目录结构。

icons/heart.png

icons/1.5x/heart.png

icons/2.0x/heart.png

获取资源文件

需要从package中获取资源文件,需要提供package的参数。我们需要在项目中的 pubspec.yaml 文件里加上具体的asset文件:

flutter: assets:

然后可以如下使用

AssetImage('icons/heart.png');

在package中的资源

如果需要从package中获取资源文件,必须提供package参数。加入下面的结构位于一个名为 my_icons 的包中,然后获取图像:

AssetImage('icons/heart.png', package: 'my_icons')

如果在package的pubspec.yaml中指定了所需资源,则会自动将其与应用程序捆绑在一起。 特别是,package本身使用的资产必须在pubspec.yaml中指定。

package 还可以选择在其'lib /'文件夹中具有未在其pubspec.yaml中指定的资源。 在这种情况下,对于要捆绑的图像,应用程序必须指定要包含的图像。 例如,名为fancy_backgrounds的包可能具有

lib/backgrounds/background1.png

lib/backgrounds/background2.png

lib/backgrounds/background3.png

比如说第一张图片,应用程序的pubspec.yaml应该在资源部分指定它:

assets: -packages/fancy_backgrounds/backgrounds/background1.png lib /是隐含的,因此它不应包含在 assets 路径中。 以下demo分别作为背景图片和配合Image使用

实现代码为

class ImageDemo extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Column(
          children: <Widget>[
           Padding(
             child:  CircleAvatar(
               backgroundImage: AssetImage('assets/images/food01.jpeg'),
             ),
             padding: EdgeInsets.only(top: 40),
           ),
            Container(
              decoration: BoxDecoration(color: Colors.red),
              child: Image(
                //类似于centerCrop
//                fit: BoxFit.cover,
                //这是图片的默认适应规则,图片会在保证图片本身长宽比不变的情况下缩放以适应当前显示空间,图片不会变形
                fit: BoxFit.contain,
                //类似于Android的fitXY,即将图片的宽高缩放到view的宽高,而且不一定是原比例
//                fit: BoxFit.fill,
                //等比例缩放直到图片宽度缩放到指定大小为止
//                fit: BoxFit.fitWidth,
                //等比例缩放直到图片高度缩放到指定大小为止
//                fit: BoxFit.fitHeight,
                image: AssetImage('assets/images/food02.jpeg'),
                height: 300.0,
                width: 300.0,
              ),
            )
          ],
        ),
      ),
    );
  }
}

DecorationImage:修饰box的图片,一般配合BoxDecoration的img属性使用,设置背景图片,也可以配合paintImage使用

Container(
  child: Center(
    child: Text(
      'Container',
      style: TextStyle(color: Colors.red),
    ),
  ),
  height: 200.0,
  width: 200.0,
  decoration: BoxDecoration(
    color: Colors.blueAccent,
    image: DecorationImage(
        image: AssetImage('assets/images/food02.jpeg'), fit: BoxFit.cover),
  ),
  margin: const EdgeInsets.only(top: 10.0),
)

ExactAssetImage:带有scale属性的AssetImage,用法与AssetImage类似 FadeInImage:它是一种placeHolderImg到目标图片的一种过渡widget,类似于glide加载时设置fadeIn而且设置了placeHolder,所以使用FadeInImage可以优雅的实现加载网络图片。它的使用方式有两种

  • FadeInImage.assetNetwork:这种方式它的placeHolderImg是从asset中取
  • FadeInImage.memoryNetwork:这种方式它的placeHolderImg是从memory中取 它的基本用法如下
ClipOval(
  child:  FadeInImage.assetNetwork(
    placeholder: "assets/images/normal_user_icon.png", //预览图
    fit: BoxFit.fitWidth,
    image:
    "https://img.alicdn.com/tfs/TB148sWfMHqK1RjSZFgXXa7JXXa-536-482.png",
    width: 160.0,
    height: 160.0,
  ),
)

FileImage:用于展示本地文件,将指定的file对象解码为图片,可以指定缩放scale 使用起来也非常简单其实就是一行代码

Image.file( _image, scale: 0.5,fit: BoxFit.cover,) 这里的_image是一个file,当然还有其他属性可以设置

NetworkImage:展示网络图片的image,可以有如下两种使用方式Image.network以及Image(image:NetworkImage)

class NetworkImageDemo extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new Scaffold(
       body: Column(
          children: <Widget>[
            Container(
              margin: const EdgeInsets.symmetric(vertical: 20.0),
              child: Text('Image.network的使用'),
            ),
            Image.network(
                'https://gw.alicdn.com/tfs/TB1XD.ZuYwrBKNjSZPcXXXpapXa-255-251.png'),
            Container(
              child: Text('NetworkImage的使用,带有0.5倍缩放'),
              margin: const EdgeInsets.symmetric(vertical: 20.0),
            ),
            Image(
              image: NetworkImage(
                  'https://gw.alicdn.com/tfs/TB1XD.ZuYwrBKNjSZPcXXXpapXa-255-251.png',
                  scale: 0.5),
            )
          ],
        )
    );
  }
}