Flutter--資源管理

Flutter的資源類型

Flutter可以添加代碼以及assets到APP中。而每個(gè)Asset都是被打包在發(fā)布的APP中的,并且在APP運(yùn)行時(shí)可以訪問(wèn)這些資源。

通用的Asset類型包括:

  • JSON文件
  • 配置文件
  • 圖標(biāo)
  • 位圖(JPEG、Webp、Gif、Animated Gif/Webp、PNG)

指定Asset

Flutter使用項(xiàng)目根目錄下的pubspec.yaml文件來(lái)指定APP所需要的資源。

  • 單個(gè)文件指定:
flutter:
  assets:
    - assets/my_icon.png
    - assets/background.png
  • 文件夾指定:
    通過(guò)指定目錄名+/字符即可,只有在該目錄下的所有文件可以被包括,如果該目錄還有子目錄的話,則需要添加一個(gè)新的Entry。
flutter:
  assets:
    - assets/
    - assets/image/

Asset Variants

構(gòu)建系統(tǒng)支持Asset Variants的概念:
在不同的環(huán)境下,需要顯示不同版本的資源。

例如,日夜間模式的資源,資源名相同,但是環(huán)境不同。

當(dāng)一個(gè)資源的路徑在pubspec.yaml文件的assets Section中指定的時(shí)候,構(gòu)建系統(tǒng)就會(huì)在相鄰的子目錄中查找相同的名稱的資源文件。而查找到的這些文件也會(huì)被打到Asset Bundle中。

例如:有一個(gè)background.png文件,在日夜間都需要使用,graphics中存放日間資源,而dark中存放夜間資源。

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

而在pubspec.yaml文件中,將background.png添加到assets的Section中。

flutter:
  assets:
    -  graphics/background.png

最終,在打包的時(shí)候會(huì)把.../graphics/background.png.../graphics/dark/background.png都打到Bundle中。而前一個(gè)被認(rèn)為是Main Bundle,而后一個(gè)則認(rèn)為是Variant Bundle。

而如果使用:

flutter:
  assets:
    - graphics/

myicon.pngbackground.png,/dark/background.png也都會(huì)打到Bundle中。

Flutter目前使用Asset Variant來(lái)解決圖片適配的問(wèn)題,而未來(lái)這種機(jī)制也會(huì)應(yīng)用在不同的語(yǔ)言等其他地方。

加載Assets

APP可以通過(guò)AssetBundle對(duì)象來(lái)訪問(wèn)資源。

  • 加載String/Text:通過(guò)loadString方法
  • 加載圖片/二進(jìn)制文件:通過(guò)load方法

而在Build的階段,邏輯Key會(huì)根據(jù)pubspec.yaml文件中的路徑來(lái)進(jìn)行映射。

每個(gè)Flutter App都有一個(gè)rootBundle對(duì)象來(lái)方便的訪問(wèn)主資源Bundle。可以通過(guò)package:flutter/services.dard中的全局靜態(tài)變量rootBundle來(lái)直接訪問(wèn)資源。不過(guò)還是推薦使用當(dāng)前的BuildContext來(lái)獲取DefaultAssetBundle,通過(guò)調(diào)用DefaultAssetBundle.of(context)來(lái)獲取。

而當(dāng)沒(méi)有Context的Widget,則需要通過(guò)rootBundle來(lái)獲取。

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

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

圖片加載的適配

Flutter會(huì)根據(jù)當(dāng)前設(shè)備的設(shè)備像素比(device Pixel Ratio)來(lái)選擇圖片。

AssetImage知道如何映射到最相近的設(shè)備像素比的圖片,為了讓Mapping能夠更好的工作,Assets應(yīng)該有這種結(jié)構(gòu):

  .../my_icon.png
  .../2.0x/my_icon.png
  .../3.0x/my_icon.png

默認(rèn)主資源Bundle中是1.0x的圖片。

例如,當(dāng)前設(shè)備的設(shè)備像素比是1.8,則會(huì)選擇/2.0x/my_icon.png。如果是2.7時(shí),則會(huì)選擇/3.0x/my_icon.png。

如果Image控件的寬高都沒(méi)有指定的話,通常的解決方案是進(jìn)行資源壓縮,然后和主資源Bundle中的圖占據(jù)相同的像素空間。

例如,1.0x的my_icon.png是72px * 72px,而3.0x的my_icon.png是216px * 216px,但是它需要繪制到72px * 72px的Image控件上,如果這個(gè)控件的寬高沒(méi)有指定的話。

加載圖片

在Widget的build函數(shù)中使用AssetImage類來(lái)加載圖片。

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

與平臺(tái)共享資源

Flutter的Asset資源也可以與Android/Ios共享。例如,flutter中有heart.png這張圖

flutter:
  assets:
    - icons/heart.png

Android:

Android上通過(guò)AssetManager來(lái)獲取。

  • 通過(guò)PluginRegistry.RegistrarlookupKeyForAsset來(lái)獲取文件路徑
  • 通過(guò)FlutterViewgetLookupKeyForAsset來(lái)獲取文件路徑
  • 通過(guò)AssetManageropenFd來(lái)得到文件描述符
AssetManager assetManager = registrar.context().getAssets();
String key = registrar.lookupKeyForAsset("icons/heart.png");
AssetFileDescriptor fd = assetManager.openFd(key);

IOS:

IOS上通過(guò)NSBundle來(lái)獲取。

  • 通過(guò)FlutterPluginRegistrarlookupKeyForAsset來(lái)獲取文件路徑
  • 通過(guò)FlutterViewController.FlutterPluginRegistrar同樣也可以獲取文件路徑
  • 通過(guò)NSBundlepathForResource來(lái)獲取文件路徑
NSString* key = [registrar lookupKeyForAsset:@"icons/heart.png"];
NSString* path = [[NSBundle mainBundle] pathForResource:key ofType:nil];

資料

Adding assets and images

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容