美文网首页flutter dartFlutter
Flutter 学习笔记 08 - 添加资源和图片

Flutter 学习笔记 08 - 添加资源和图片

作者: 三流之路 | 来源:发表于2019-01-03 20:38 被阅读145次

Flutter 可以包含 assets,asset 是打包到程序安装包中的,可在运行时访问。常见类型的 asset 包括静态数据(比如 JSON 文件),配置文件,图标和图片 (JPEG, WebP, GIF, animated WebP/GIF, PNG, BMP, WBMP)。

指定 assets

Flutter 使用 pubspec.yaml 文件来识别应用程序所需的 asset。

flutter:
  assets:
    - images/my_icon.png
    - assets/background.png

asset 的声明顺序无关紧要,实际目录可以是任意文件夹。这些文件会被放入一个特殊的地方叫 asset bundle,可以在运行时读取。

比如根目录下有如下文件:

.../pubspec.yaml
.../graphics/my_icon.png
.../graphics/background.png
.../graphics/dark/background.png

pubspec.yaml 配置为:

flutter:
  assets:
    - graphics/background.png

那么 graphics/background.pnggraphics/dark/background.png 将包含在 asset bundle 中。前者被认为是 main asset,后者被认为是一种变体 variant

如果配置为:

flutter:
  assets:
    - graphics/

那么 graphics/my_icon.png, graphics/background.pnggraphics/dark/background.png 都会被放到 asset bundle 中。

在选择匹配当前设备分辨率的图片时,Flutter 使用 asset 变体。

加载 assets

通过 AssetBundle 访问 asset。

  • loadString 方法加载字符串或文本 text
  • load 方法加载图片或二进制文件

加载文本 assets

每个 Flutter 应用程序都有一个 rootBundle 对象,可以访问主 asset bundle。

可以直接使用 package:flutter/services.dart 中的全局静态的 rootBundle 对象来加载asset。

但是最好使用 DefaultAssetBundle 来获取当前 BuildContext 的 AssetBundle。这种方法不是使用应用程序构建的默认 asset bundle,而是使父级 widget 在运行时替换的不同的 AssetBundle,这对于本地化或测试场景很有用。通常,可以使用 DefaultAssetBundle.of() 从应用运行时间接加载asset。

在 Widget 上下文之外,或 AssetBundle 的句柄不可用时,可以使用 rootBundle 直接加载这些 asset,例如:

import 'dart:async' show Future;
import 'package:flutter/services.dart' show rootBundle;

Future<String> loadAsset() async {
  return await rootBundle.loadString('assets/config.json');
}

加载图片

Flutter 可以为当前设备加载适合其分辨率的图像。

声明分辨率相关的图片 assets

AssetImage 了解如何将逻辑请求 asset 映射到最接近当前设备像素比例的 asset。为了使这种映射起作用,应该根据特定的目录结构来保存 asset

…/image.png
…/Mx/image.png
…/Nx/image.png

其中 MN 是数字标识符,对应于其中包含的图像的分辨率,也就是说,它们指定不同像素设备比例的图片,主资源默认对应于 1.0 倍的分辨率图片,比如:

…/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 控件上指定渲染图像的宽度和高度,那么它将占用与主资源相同的屏幕空间量,只是分辨率更高。也就是说,如果 .../my_icon.png72px \times 72px,那么 .../3.0x/my_icon.png 应该是 216px \times 216px,但如果未指定宽度和高度,它们都将渲染为 72px \times 72px(以逻辑像素为单位)。

pubspec.yaml 中 asset 部分中的每一项都应与实际文件相对应,但主资源项除外。当主资源缺少某个资源时,会按分辨率从低到高的顺序去选择,即如果 1x 中没有的话会到 2x 中找,2x 中还没有的话到 3x 中找。

加载图片

Widget build(BuildContext context) {
  // ...
  return DecoratedBox(
    decoration: BoxDecoration(
      image: DecorationImage(
        // 系统会根据分辨率自动选择不同大小的图片
        image: AssetImage('graphics/background.png'),
        // ...
      ),
      // ...
    ),
  );
  // ...
}

使用默认的 asset bundle 加载资源时,内部会自动处理分辨率。

依赖包中的资源

资源在 pubspec.yaml 中声明

要加载依赖包中的图像,必须给 AssetImage 提供 package 参数。

假设应用程序依赖于一个名为“my_icons”的包,它具有如下目录结构:

…/pubspec.yaml
…/icons/heart.png
…/icons/1.5x/heart.png
…/icons/2.0x/heart.png

然后加载图像,使用:

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

包使用的本身的资源也应该加上 package 参数来获取。

资源在 lib/ 包下

pubspec.yaml 文件中声明的资源会打包到 package 中。如果资源直接放在 lib/ 文件夹且未在 pubspec.yaml 文件中声明。那么应用程序必须在自己的 pubspec.yaml 中指定包含哪些资源。比如,一个名为“fancy_backgrounds”的包,可能包含以下文件:

…/lib/backgrounds/background1.png
…/lib/backgrounds/background2.png
…/lib/backgrounds/background3.png

要使用第一张图像,必须在 pubspec.yaml 中声明:

flutter:
  assets:
    - packages/fancy_backgrounds/backgrounds/background1.png

lib/ 是隐含的,不应该包含在路径中。

Android 中使用 Flutter 中的资源

Flutter 中有一个图标文件:

flutter:
  assets:
    - icons/heart.png

在 Android 代码中要使用 Flutter 的资源,从 FlutterView 中获取 PluginRegistry.Registrar,通过它的 lookupKeyForAsset 方法获取一个 key。

// registrar 是 PluginRegistry.Registrar 对象
AssetManager assetManager = registrar.context().getAssets();
String key = registrar.lookupKeyForAsset("icons/heart.png");
AssetFileDescriptor fd = assetManager.openFd(key);

Flutter 使用 Android/iOS 资源改变 icon 和 splash

替换启动图标:

Android 只要到 /android/app/src/main/res/ 中替换图片即可。iOS 到 /ios/Runner/Assets.xcassets/AppIcon.appiconset 中替换即可。

替换 Splash 内容:

Android 修改 /android/app/src/main/res/drawable/launch_background.xml 文件。

iOS 要将图片添加到启动屏幕的中心,到 /ios/Runner/Assets.xcassets/LaunchImage.imageset 中拖入图片,并命名为 images LaunchImage.png、LaunchImage@2x.png、LaunchImage@3x.png。如果使用不同的文件名,还必须更新同一目录中的 Contents.json 文件。

相关文章

网友评论

    本文标题:Flutter 学习笔记 08 - 添加资源和图片

    本文链接:https://www.haomeiwen.com/subject/ygwqrqtx.html