Flutter | 资源管理

简介: Flutter | 资源管理

Flutter 安装包中会包含代码和 assets 资源两部分,Assets 是会打包到程序安装包中的,可在运行时访问。常见类型的 assets 包括静态数据,如 json ,配置文件,图片,MP3,gif 等。


加载图片


例如加载一张图片,在 Flutter 中使用 pubspec.yaml 文件来管理所需要的文件


在加载图片之前,需要在根目录下创建一个文件夹,里面存放图片,以及它所对应分辨率的图片


如上图,创建了 images 文件夹,然后放入图片,并创建对应分辨率的文件夹,将图片放进去即可


注意:flutter 默认是必须要创建 2.0x 和 3.0x,至于4.0x,可自行选择


图片准备好之后,就可以通过 pubspec.yaml 文件进行配置


flutter:
  uses-material-design: true
  assets:
    - images/icon.png
    - images/2.0x/icon.png
    - images/3.0x/icon.png
    - images/4.0x/icon.png


接着就可以显示图片了


class AssetsLoad extends StatefulWidget {
  @override
  State<StatefulWidget> createState() {
    return _AssetsLoadState();
  }
}
class _AssetsLoadState extends State<AssetsLoad> {
  var imageID = "";
void uploadImage() {
    setState(() {
    imageID = "images/icon.png";
    });
  }
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("资源加载"),
      ),
      body: Column(
        children: [
          Center(
            child: Container(
              child: Image.asset("$imageID", fit: BoxFit.cover),
              width: 100,
              height: 100,
            ),
          ),
          RaisedButton(
            onPressed: () {
              uploadImage();
            },
            child: Text("加载图片"),
          )
        ],
      ),
    );
  }
}


效果如下所示


分辨率2.0x,3.0x,4.0x


当设备像素比(device pixel ratio) < 1 时候,images/icon.png 的图片将会被使用。

当设备像素比 1 < (device pixel ratio) < 2 时候,images/2.0x/icon.png 的图片将会被使用。

当设备像素比 2 < (device pixel ratio) < 3 时候,images/3.0x/icon.png 的图片将会被使用,


当 > 3 的时候,4.0x 中的图片会被调用


Flutter 最终会根据设备像素比例,去获取对应分辨率的图片


pubspec.yaml 中 asset 部分中的每一项应与实际文件相对应,但是主资源除外,当主资源缺少某个文件时,会按照分辨率从低到高的顺序去选择。


Asset 变体(variant)


构建过程支持变体概念:不同版本的 asset 可能会显示在不同的上下文中。在 pubspec.yaml 的 assets 部分指定路径时,构建过程中,会在相邻的子目录去查找具有相同名称的任何文件,这些文件随后会与指定的 asset 一起被包含在 asset bundle 中。


例如


.../pubspec.yaml
.../images/icon.png
.../images/2.0x/icon.png


然后在 pubspec.yaml 中,只需要包含:


flutter:
  assets:
    - images/icon.png


那么这两个 images/icon.png 和 images/2.0x/icon.png 都将包含在 asset bundle 中。前者被认为是 main asset(主资源),后者被认为是一种变体(variant)


在选择设备当前分辨率时,Flutter 会用到 asset 变体,将来,Flutter 可能会将这种机制扩展到本地化,阅读提示等方面


因此,在上面加载图片中,pubspec.yaml 文件可以直接使用如下写法:


flutter:
  uses-material-design: true
  assets:
    - images/icon.png


加载依赖包中的资源图片


new Image.asset('icons/heart.png', package: 'my_icons')


例如,如果要加载一个名字为 fancy_backgrounds 的包,那么他的资源文件应该是


…/lib/backgrounds/background1.png


…/lib/backgrounds/background2.png


…/lib/backgrounds/background3.png


而对应的在 pubspec.yaml 中也应该进行声明


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


加载文本assets


通过 rootBundle 对象加载,每个 Flutter 都有一个 rootBundle 对象,通过他可以轻松访问主资源包,直接使用 package:flutter/services.dart 中全局的 rootBundle 对象来加载 assets 即可


通过 DefaultAssetBundle来加载,建议使用 DefaultAssetBundle 来获取当前 BuildContext 的 AssetBundle 。


这种方法不是使用应用程序构建默认的 asset bundle,而是使用父级 widget 在运行时动态替换不同的 AssetBundle,这对本地化或测试场景会很有用


通常可以使用 DefalutAssetBundle.of()在应用运行时来间接加载 asset(例如 json 文件),而在 widget 上下文之外,或者其他 AssetBundle 不可用时, 可以使用 routBundle直接加载 asset


class AssetsLoad extends StatefulWidget {
  @override
  State<StatefulWidget> createState() {
    return _AssetsLoadState();
  }
}
class _AssetsLoadState extends State<AssetsLoad> {
  var imageID = "";
  var text = "";
  void uploadImage() {
    setState(() {
      imageID = "images/icon.png";
    });
  }
  Future<String> loadText() async {
    return await rootBundle.loadString("assets/file.txt");
  }
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("资源加载"),
      ),
      body: Column(
        children: [
        //.......
          Container(
            child: Center(
              child: Text(
                text,
                textAlign: TextAlign.center,
              ),
            ),
            width: 100,
            height: 100,
          ),
          RaisedButton(
            onPressed: () {
              loadText().then((value) {
                setState(() {
                  text = value;
                });
              });
            },
            child: Text("加载文本"),
          )
        ],
      ),
    );
  }
}


如上所示,调用 loadText 可以获取到文件中的内容,注意,该文件需要在 pubspec.yaml中进行声明


效果如下:


设置 APP 图标


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


Android


在 flutter 根目录中,找到 .../android/app/src/main/res 目录,例包含了各种资源文件夹,如 mipmap 等,找到名字为 ic_launcher.png 的图片,然后替换即可,注意,需要遵守每种屏幕密度(dpi)的建议图标大小标准即可


iOS


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


更新启动页


在 Flutter 框架加载时,Flutter 会使用本地机制绘制启动项,此启动页将持续到 Flutter 渲染应用程序的第一帧时


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


Android


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


<!-- Modify this file to customize your launch splash screen -->
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="?android:colorBackground" />
    <!-- You can insert your own image assets here -->
     <item>
        <bitmap
            android:gravity="center"
            android:src="@drawable/launch_image" />
    </item>
</layer-list>


iOS


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


您也可以通过打开Xcode完全自定义storyboard。在Project Navigator中导航到Runner/Runner然后通过打开Assets.xcassets拖入图片,或者通过在LaunchScreen.storyboard中使用Interface Builder进行自定义


问题


1,使用本地图片之后,需要重新运行项目,而不是启用热重载,如果使用热重载,可能会导致错误,或者是图片加载不出来


2,在 pubspec.yaml 中,一定要注意规范,避免出现多余的空格等 ,否则可能会出现异常


3,在 pubspec.yaml 中需要将所有使用到的图片全部声明出来,虽然在知道变体以后一张图片只需要写一次,但是仍然会非常麻烦,这个时候可以使用一个相对路径来标识,如:


flutter:
  uses-material-design: true
  assets:
    - images/
相关文章
在 Flutter 中如何使用 ChangeNotifierProvider 实现数据共享?
在 Flutter 中如何使用 ChangeNotifierProvider 实现数据共享?
|
20天前
|
存储 开发者
Flutter&鸿蒙next 使用 BLoC 模式进行状态管理详解
本文详细介绍了如何在 Flutter 中使用 BLoC 模式进行状态管理。BLoC 模式通过将业务逻辑与 UI 层分离,利用 Streams 和 Sinks 实现状态管理和 UI 更新,提高代码的可维护性和可测试性。文章涵盖了 BLoC 的基本概念、实现步骤及代码示例,包括定义 Event 和 State 类、创建 Bloc 类、提供 Bloc 实例以及通过 BlocBuilder 更新 UI。通过一个简单的计数器应用示例,展示了 BLoC 模式的具体应用和代码实现。
71 1
|
20天前
|
缓存 JavaScript API
Flutter&鸿蒙next 状态管理框架对比分析
在 Flutter 开发中,状态管理至关重要,直接影响应用的性能和可维护性。本文对比分析了常见的状态管理框架,包括 setState()、InheritedWidget、Provider、Riverpod、Bloc 和 GetX,详细介绍了它们的优缺点及适用场景,并提供了 Provider 的示例代码。选择合适的状态管理框架需考虑应用复杂度、团队熟悉程度和性能要求。
84 0
|
2月前
|
JSON Dart Java
flutter开发多端平台应用的探索
flutter开发多端平台应用的探索
51 6
|
6月前
|
Dart IDE API
Flutter Riverpod 状态管理上手技巧分享
时代在进步 Riverpod 作为一个优秀的状态管理,猫哥也开始做些技术调研。今天会写两个例子,计数器、拉取数据。
153 1
Flutter Riverpod 状态管理上手技巧分享
|
6月前
|
JSON Dart UED
Flutter 应用程序性能优化建议
Flutter应用程序默认已经具有良好的性能,因此您只需要避免常见的陷阱,就可以获得出色的性能。 您设计和实现应用程序的用户界面的方式可能会对其运行效率产生重大影响。 本文这些最佳实践建议将帮助您编写性能最佳的Flutter应用程序。
121 3
Flutter 应用程序性能优化建议
|
缓存 Dart 前端开发
Flutter 中使用 Widgetbook 管理你的组件 | 猫哥
Flutter 界面开发中我们有几个痛点 : - 与设计师协作复用一套设计规范(figma) - 可视化的管理你的组件代码(基础组件、业务组件) - 不同设备尺寸测试你的组件 - 实时修改你的测试组件参数
4260 1
Flutter 中使用 Widgetbook 管理你的组件 | 猫哥
|
6月前
|
缓存 Dart 开发者
Flutter 最佳实践
Flutter 最佳实践 Flutter 是一个快速开发高质量、高性能移动应用程序的工具。如果你想要保证项目的质量和效率,那么在使用 Flutter 进行项目开发时,遵循一些最佳实践是非常必要的。
134 0
|
编解码 JSON 数据格式
Flutter | 一起学资源管理
Flutter安装包中会包含代码和assets (资源)两部分,其中 assets 是会打包到程序安装包中,可以运行时访问,常见的 assets 类型包括静态数据(json文件),配置文件,图标和图片等。
142 0
|
Web App开发 Dart 安全
flutter项目迁移空安全
迁移 你的代码里大部分需要更改的代码,都是可以轻易推导的。例如,如果一个变量可以为空,它的类型需要 ? 后缀。一个不可以为空的命名参数,需要使用 required 标记。
297 0
flutter项目迁移空安全
下一篇
无影云桌面