Flutter 资源文件 Adding assets and images
Posted 猴子自习室
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Flutter 资源文件 Adding assets and images相关的知识,希望对你有一定的参考价值。
今天临时插播一条内容,因为在工作中有小伙伴对Flutter的assets and images有些疑问,查了查文档也不太明白,今天我们就一步一步看看Flutter的assets到底怎么使用。
Flutter应用可以同时包含代码和资产(也称为资源)。资产是与您的应用程序捆绑和部署的文件,可在运行时访问。资产的常见类型包括静态数据(如JSON文件),配置文件,图标和图像(JPEG,WebP,GIF,动画WebP / GIF,PNG,BMP和WBMP)。
指定资产
Flutter使用位于项目根目录的pubspec.yaml文件来标识应用程序需要的资产。例如:
flutter:
assets:
assets/my_icon.png
assets/background.png
有的同学可能要有疑问了
文件夹的名字是固定的吗?
如果这个文件夹图片特别多怎么办?
问题1:文件夹的名字是可以更改的。
问题2:我们可以设置到目录级别,类似这样。
flutter:
assets:
directory/
directory/subdirectory/
子目录的子目录也需要这样配置,注意要以 ‘/’结尾。
Asset bundling
Flutter中的assets部分都应该在pubspec.yaml文件资产部分中配置。在构建期间,Flutter会将资产放入Asset bundling,应用程序可在运行时从中读取。
Asset variants
构建过程支持资产变体的概念:资产的不同版本可能会在不同的上下文中显示。在pubspec.yaml的资产部分中指定了资产路径后,构建过程将在相邻子目录中查找具有相同名称的所有文件。然后,将这些文件与指定的资产一起包括在Asset bundling中。例如:你的项目中是这样的
.../pubspec.yaml
.../graphics/my_icon.png
.../graphics/background.png
.../graphics/dark/background.png
...etc.
在pubspec.yaml中配置
flutter:
assets:
graphics/background.png
这样,dark就以变体的形式存在了。当然,你也可以配置到目录,效果是一样的。
flutter:
assets:
graphics/
在选择适合分辨率的图像时,Flutter使用资产变体。将来,可能会扩展此机制,以包括针对不同语言环境或区域,阅读方向等的变体。
Loading assets
我们可以通过AssetBundle对象访问其资产。
Asset bundling允许加载字符串/文本资产loadString()或图像/二进制资产load()。在build阶段,pubspec.yaml中配置的路径,映射到logical key maps中。
Loading text assets
每个Flutter应用程序都有一个rootBundle对象访问主资产包。可以使用package:flutter / services.dart中的rootBundle全局静态变量直接加载资产。
但是,建议使用DefaultAssetBundle而不是应用程序构建的默认资产捆绑包来获取当前BuildContext的AssetBundle;这种方法使父窗口小部件可以在运行时替换不同的AssetBundle,这对于本地化或测试场景很有用。
通常,您将使用DefaultAssetBundle.of()从应用程序的运行时rootBundle间接加载资产(例如JSON文件)。当然,如果在Widget上下文之外,或者当AssetBundle的句柄不可用时,您可以使用rootBundle直接加载此类资产。例如:
import 'dart:async' show Future;
import 'package:flutter/services.dart' show rootBundle;
Future<String> loadAsset() async {
return await rootBundle.loadString('assets/config.json');
}
Loading images
Flutter可以为当前设备的像素比率加载适合分辨率的图像。AssetImage了解选取与当前设备像素比率最接近的资产。同时我们的目录结构应该如下:
.../image.png
.../Mx/image.png
.../Nx/image.png
...etc.
其中M和N是数字标识符,对应于其中包含的图像的分辨率。换句话说,它们指定了图像打算用于的设备像素比率。
假定主要资产对应于1.0的分辨率。例如,对于名为my_icon.png的图像,请考虑以下资产布局:
.../my_icon.png
.../2.0x/my_icon.png
.../3.0x/my_icon.png
在设备像素比为1.8的设备上,选择资产... / 2.0x / my_icon.png。对于2.7的设备像素比率,选择资产... / 3.0x / my_icon.png。
如果未在image widget上指定渲染图像的宽度和高度,则将使用标称分辨率缩放资产,以便它以更高的分辨率占用与主要资产相同的屏幕空间。如果... / my_icon.png为72px x 72px,则... / 3.0x / my_icon.png应该为216px x 216px;但是如果未指定width和height,它们都将渲染为72px x 72px(单位是逻辑像素),3.0x下的图片将按3.0进行缩放。
注意:设备像素比率取决于MediaQueryData.size,该参数要求使用MaterialApp或CupertinoApp作为AssetImage的祖先。每个逻辑像素的设备像素数。这个数可能不会是二的幂。实际上,它甚至可能不是整数。例如,Nexus 6的装置像素比例为3.5。(实际上,我们也可以使用MediaQuery.of(context).devicePixelRatio来查看当前设备的像素比。
images实践
我准备了4张100x100的图片。
import 'package:flutter/material.dart';
class AssetsPage extends StatelessWidget {
Widget build(BuildContext context) {
var devicePixelRatio = MediaQuery.of(context).devicePixelRatio;
return Scaffold(
appBar: AppBar(
title: Text('测试assets 设备PixelRatio $devicePixelRatio'),
),
body: Container(
color: Colors.black,
child: Center(
child: Image.asset('images/img/test.jpg'),
),
),
);
}
}
按着文档配置好,这里没有指定到2.0x下,只是指定到了文件夹,并且文件夹的名字也经过了更改,我们来看看效果。
我们看到设备devicePixelRatio是3.0,图片显示也是正常,如果我们删除img下的x.0文件夹。再来看看效果。
因为我们使用的图片都是100x100的,并且没有设置width和height,那么按照Flutter的要求,如果我们想要在设备上显示同样的效果,3.0x中应该使用300x300的图标,应为3.0x下的图片将会缩放显示。
assets:
images/img/2.0x/
images/img/3.0x/
这种情况下是无法正常load image的。 接下来我们恢复原来的配置,继续测试。
这是一个3.5的设备,向下选取了3.0x的图片,我们将3.0x删除在试试效果。
可以看到走到了4.0x,我们在把4.0x删除,走到了2.0x的目录中。这个结果说明,Flutter的机制是选取距离目标像素比例最接近的目录。当然笔者还做了好多测试,比如1.9x,2.0x等等,感兴趣的同学可以自己试一试,对于这部分的源码,会在后面的文章中更新,小伙伴不要着急,今天这个部分也只是项目遇到应急写出来的,欢迎大家指正。接下来的文章还是会继续将常用Widget逐一介绍,在最后的系列中,会公开一个商业级的项目,感兴趣的小伙伴关注。如果您在阅读过程中发现错误,请及时留言给我,我会第一时间改正。也欢迎大家一切交流,共同进步,感谢支持!
以上是关于Flutter 资源文件 Adding assets and images的主要内容,如果未能解决你的问题,请参考以下文章
需要在 Flutter web view 中使用 src 通过 HTML 添加图片资源
Flutter小记2Android加载图片资源出现Unable to load asset的解决方案