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 实现数据共享?
|
3月前
|
传感器 前端开发 Android开发
在 Flutter 开发中,插件开发与集成至关重要,它能扩展应用功能,满足复杂业务需求
在 Flutter 开发中,插件开发与集成至关重要,它能扩展应用功能,满足复杂业务需求。本文深入探讨了插件开发的基本概念、流程、集成方法、常见类型及开发实例,如相机插件的开发步骤,同时强调了版本兼容性、性能优化等注意事项,并展望了插件开发的未来趋势。
63 2
|
3月前
|
存储 开发者
Flutter&鸿蒙next 使用 BLoC 模式进行状态管理详解
本文详细介绍了如何在 Flutter 中使用 BLoC 模式进行状态管理。BLoC 模式通过将业务逻辑与 UI 层分离,利用 Streams 和 Sinks 实现状态管理和 UI 更新,提高代码的可维护性和可测试性。文章涵盖了 BLoC 的基本概念、实现步骤及代码示例,包括定义 Event 和 State 类、创建 Bloc 类、提供 Bloc 实例以及通过 BlocBuilder 更新 UI。通过一个简单的计数器应用示例,展示了 BLoC 模式的具体应用和代码实现。
134 1
|
3月前
|
缓存 JavaScript API
Flutter&鸿蒙next 状态管理框架对比分析
在 Flutter 开发中,状态管理至关重要,直接影响应用的性能和可维护性。本文对比分析了常见的状态管理框架,包括 setState()、InheritedWidget、Provider、Riverpod、Bloc 和 GetX,详细介绍了它们的优缺点及适用场景,并提供了 Provider 的示例代码。选择合适的状态管理框架需考虑应用复杂度、团队熟悉程度和性能要求。
156 0
|
5月前
|
JSON Dart Java
flutter开发多端平台应用的探索
flutter开发多端平台应用的探索
64 6
|
缓存 Dart 前端开发
Flutter 中使用 Widgetbook 管理你的组件 | 猫哥
Flutter 界面开发中我们有几个痛点 : - 与设计师协作复用一套设计规范(figma) - 可视化的管理你的组件代码(基础组件、业务组件) - 不同设备尺寸测试你的组件 - 实时修改你的测试组件参数
4277 1
Flutter 中使用 Widgetbook 管理你的组件 | 猫哥
|
9月前
|
缓存 Dart 开发者
Flutter 最佳实践
Flutter 最佳实践 Flutter 是一个快速开发高质量、高性能移动应用程序的工具。如果你想要保证项目的质量和效率,那么在使用 Flutter 进行项目开发时,遵循一些最佳实践是非常必要的。
150 0
|
Dart Linux 开发工具
使用Flutter构建桌面应用:一次开发,多平台支持
随着移动和桌面应用程序的需求不断增长,开发人员需要寻找一种高效的方法来构建多平台的应用程序。Flutter作为一个跨平台的UI框架,提供了一次编写、多平台运行的解决方案。在本文中,我们将探讨如何使用Flutter来构建桌面应用程序,并展示其多平台支持的优势。
1957 0
|
编解码 JSON 数据格式
Flutter | 一起学资源管理
Flutter安装包中会包含代码和assets (资源)两部分,其中 assets 是会打包到程序安装包中,可以运行时访问,常见的 assets 类型包括静态数据(json文件),配置文件,图标和图片等。
157 0
|
存储 前端开发 API
Flutter 状态管理概述【Flutter 专题 7】
Flutter 状态管理:概述 状态管理是 UI 框架必须实现的关键特性之一并且实现得很好。正是出于这个原因,许多开发人员已经开始构建专用的状态管理库;内置的解决方案对他们来说还不够,或者他们想根据自己的口味进行调整。
188 0
Flutter 状态管理概述【Flutter 专题 7】

热门文章

最新文章