Flutter学习四:Flutter开发基础(五)资源管理

目录

0 引言

1 资源管理

1.1 指定 assets

1.2 Asset 变体(variant)

1.3 加载 assets

1.3.1  加载文本

1.3.2 加载图片

1.3.2.1 声明分辨率相关的图片

1.3.2.2 加载图片

1.3.3 依赖包中的资源图片

 1.3.4 打包包中的 assets

1.3.5  特定平台 assets 

1.3.5.1 设置APP图标

 1.3.5.2 更新启动页

1.4 平台共享 assets


0 引言

本文是对第二版序 | 《Flutter实战·第二版》 (flutterchina.club)的学习和总结。

1 资源管理

Flutter APP 安装包中会包含代码和 assets(资源)两部分。

Assets 是会打包到程序安装包中的,可在运行时访问。

常见类型的 assets 包括静态数据(例如JSON文件)、配置文件、图标和图片等。

1.1 指定 assets

和包管理一样,Flutter 也使用pubspec.yaml 文件来管理应用程序所需的资源。

  • assets指定应用程序的资源文件
  • asset 的路径是相对于pubspec.yaml文件路径的
  • asset 的声明顺序是无关紧要的
  • asset的实际目录可以是任意文件夹
  • 在构建期间,Flutter 将 asset 放置到称为 asset bundle 的特殊存档中,应用程序可以在运行时读取它们(但不能修改)。
flutter:
  assets:
    - assets/my_icon.png
    - assets/background.png

1.2 Asset 变体(variant)

pubspec.yaml的assets 部分中指定 asset 路径时,

flutter:
  assets:
    - graphics/background.png

如果应用程序目录中有以下文件:

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

那么,在构建过程中,会在相邻子目录中查找具有相同名称的任何文件。

这些文件随后会与指定的 asset 一起被包含在 asset bundle 中,graphics/background.pnggraphics/dark/background.png 这两个文件都将包含在您的 asset bundle中。前者被认为是_main asset_ (主资源),后者被认为是一种变体(variant)。

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

1.3 加载 assets

可以通过AssetBundle 对象访问其 asset 。

1.3.1  加载文本

  • 通过rootBundle对象加载:每个Flutter应用程序都有一个rootBundle对象, 通过它可以轻松访问主资源包,直接使用package:flutter/services.dart中全局静态的rootBundle对象来加载asset即可。
  • 通过 DefaultAssetBundle加载:建议使用 DefaultAssetBundle来获取当前 BuildContext 的AssetBundle。 这种方法不是使用应用程序构建的默认 asset bundle,而是使父级 widget 在运行时动态替换的不同的 AssetBundle,这对于本地化或测试场景很有用。
  • 通常,可以使用DefaultAssetBundle.of()在应用运行时来间接加载 asset(例如JSON文件),而在widget 上下文之外,或其他AssetBundle句柄不可用时,可以使用rootBundle直接加载这些 asset
import 'dart:async' show Future;
import 'package:flutter/services.dart' show rootBundle;

/*
  1.使用rootBundle直接加载 asset(例如JSON文件)
*/
Future<String> loadAsset() async {
  return await rootBundle.loadString('assets/config.json');
}


/*
  2.使用DefaultAssetBundle.of()在应用运行时来间接加载 asset(例如JSON文件)
*/

1.3.2 加载图片

类似于原生开发,Flutter也可以为当前设备加载适合其分辨率的图像。

1.3.2.1 声明分辨率相关的图片

AssetImage可以将asset的请求逻辑映射到最接近当前设备像素比例(dpi)的asset,即使用默认的 asset bundle 加载资源时,内部会自动处理分辨率等,这些处理对开发者来说是无感知的。 (如果使用一些更低级别的类,如 ImageStream或 ImageCache时你会注意到有与缩放相关的参数)。

  • 主资源默认对应1.0倍分辨率的图片
  • 在设备像素比率为1.8的设备上,2.0倍分辨率的图片将被选择

  • 在设备像素比率为2.7的设备上,3.0倍分辨率的图片将被选择

如果未在Image widget上指定渲染图像的宽度和高度,那么Image widget将占用与主资源相同的屏幕空间大小。 也就是说,如果.../background.png是72px乘72px,那么.../3.0x/my_icon.png应该是216px乘216px; 但如果未指定宽度和高度,它们都将渲染为72像素×72像素(以逻辑像素为单位)。

flutter:
  assets:
    - graphics/background.png
    - graphics/2.0x/background.png
    - graphics/3.0x/background.png

1.3.2.2 加载图片

要加载图片,可以使用 AssetImage类。例如,我们可以从上面的asset声明中加载背景图片:

注意,AssetImage 并非是一个widget, 它实际上是一个ImageProvider。

Widget build(BuildContext context) {
  return DecoratedBox(
    decoration: BoxDecoration(
      image: DecorationImage(
        image: AssetImage('graphics/background.png'),
      ),
    ),
  );
}

如果想要直接得到一个显示图片的widget,可以使用Image.asset()方法,如:

Widget build(BuildContext context) {
  return Image.asset('graphics/background.png');
}

1.3.3 依赖包中的资源图片

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

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

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

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

/*
  加载依赖包中的图像
*/

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

//方法二:
Image.asset('icons/heart.png', package: 'my_icons')

 1.3.4 打包包中的 assets

  • 如果在pubspec.yaml文件中声明了期望的资源,它将会打包到相应的package中。
  • 包本身使用的资源必须在pubspec.yaml中声明。

例如,一个名为“fancy_backgrounds”的包,可能包含以下文件:

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

注意:lib/是隐含的,在pubspec.yaml中声明时不需要包含在内。 

要想将第一张图像打包到包中,必须在pubspec.yaml的assets部分中声明它: 

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

1.3.5  特定平台 assets 

上面的资源都是flutter应用中的,这些资源只有在Flutter框架运行之后才能使用。

如果要给我们的应用设置APP图标或者添加启动图,那我们必须使用特定平台的assets。

1.3.5.1 设置APP图标

更新Flutter应用程序启动图标的方式与在本机Android或iOS应用程序中更新启动图标的方式相同。

  • Android

    在 Flutter 项目的根目录中,导航到.../android/app/src/main/res目录,里面包含了各种资源文件夹(如mipmap-hdpi已包含占位符图像 “ic_launcher.png”)。 只需按照Android开发人员指南中的说明, 将其替换为所需的资源,并遵守每种屏幕密度(dpi)的建议图标大小标准。

  • iOS

    在Flutter项目的根目录中,导航到.../ios/Runner/Assets.xcassets/AppIcon.appiconset。该目录中已经包含占位符图片icon-App-xxxxxxxx.png, 只需将它们替换为适当大小的图片,保留原始文件名称。

 1.3.5.2 更新启动页

在 Flutter 框架加载时,Flutter 会使用本地平台机制绘制启动页。

此启动页将持续到Flutter渲染应用程序的第一帧时。

注意: 这意味着如果您不在应用程序的main()方法中调用runApp函数 (或者更具体地说,如果您不调用window.render去响应window.onDrawFrame)的话, 启动屏幕将永远持续显示。

  • Android

要将启动屏幕(splash screen)添加到您的Flutter应用程序, 请导航至.../android/app/src/main。在res/drawable/launch_background.xml,通过自定义drawable来实现自定义启动界面(你也可以直接换一张图片)。

  • iOS

要将图片添加到启动屏幕(splash screen)的中心,请导航至.../ios/Runner。在Assets.xcassets/LaunchImage.imageset, 拖入图片,并命名为LaunchImage.png[email protected][email protected]。 如果你使用不同的文件名,那您还必须更新同一目录中的Contents.json文件,图片的具体尺寸可以查看苹果官方的标准。

1.4 平台共享 assets

如果我们采用的是Flutter+原生的开发模式,那么可能会存Flutter和原生需要共享资源的情况。

比如Flutter项目中已经有了一张图片A,如果原生代码中也要使用A,我们可以将A拷贝一份到原生项目的特定目录。

这样的话虽然功能可以实现,但是最终的应用程序包会变大,因为包含了重复的资源。

为了解决这个问题,Flutter 提供了一种Flutter和原生之间共享资源的方式,实现上需要涉及平台相关的原生代码,可以自行查阅官方文档

猜你喜欢

转载自blog.csdn.net/D_lunar/article/details/131436732