一個應(yīng)用程序少不了一些靜態(tài)資源,例如:圖片、字體、配置文件等。這些靜態(tài)資源會打包到程序安裝包中,可以在運行時訪問。
Flutter 中添加靜態(tài)資源很簡單,將靜態(tài)資源放置在任意目錄(通常是根目錄下的 assets 文件夾中),然后在配置文件中 pubspec.yaml 中指定即可。每個 asset 都通過相對于 pubspec.yaml 文件所在位置的路徑進(jìn)行標(biāo)識。asset 的聲明順序是無關(guān)緊要的。
在構(gòu)建期間,F(xiàn)lutter 將 asset 放置到稱為 asset bundle 的特殊存檔中,應(yīng)用程序可以在運行時通過 AssetBundle 對象訪問。
查看示例代碼。

加載文本
每個 Flutter 應(yīng)用程序都有一個 rootBundle 對象, 可以輕松訪問主資源包,也可以直接使用 package:flutter/services.dart 中全局靜態(tài)的rootBundle 對象來加載 asset。
但是,建議使用 DefaultAssetBundle.of 來獲取當(dāng)前 BuildContext 的 AssetBundle。這種方法不是使用應(yīng)用程序構(gòu)建的默認(rèn) asset bundle,而是使父級 widget 在運行時替換的不同的 AssetBundle ,這在本地化或測試時很有用。
接下來以讀取本地 JSON 文件為例進(jìn)行說明。
創(chuàng)建 assets/person.json 文件,并寫入以下內(nèi)容:
[
{
"name": "Tom",
"age": 23,
"height": 172,
"gender": "male"
},
{
"name": "Jerry",
"age": 18,
"height": 163,
"gender": "male"
},
{
"name": "Lina",
"age": 30,
"height": 180,
"gender": "female"
}
]
在 pubspec.yaml 中配置資源:
flutter:
assets:
- assets/person.json
接著,創(chuàng)建一個頁面,用來展示 JSON 數(shù)據(jù):
import 'dart:convert' show json;
import 'package:flutter/material.dart';
class Assets extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text('Assets'),
),
body: new JsonView(),
);
}
}
class JsonView extends StatefulWidget {
@override
State<StatefulWidget> createState() {
return new _JsonViewState();
}
}
class _JsonViewState extends State<JsonView> {
@override
Widget build(BuildContext context) {
return new FutureBuilder(
future: DefaultAssetBundle.of(context).loadString("assets/person.json"),
builder: (context, snapshot) {
if (snapshot.hasData) {
List<dynamic> data = json.decode(snapshot.data.toString());
return new ListView.builder(
itemCount: data.length,
itemBuilder: (BuildContext context, int index) {
return new Card(
child: new Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
new Text("Name: ${data[index]["name"]}"),
new Text("Age: ${data[index]["age"]}"),
new Text("Height: ${data[index]["height"]}"),
new Text("Gender: ${data[index]["gender"]}"),
],
),
);
},
);
}
return new CircularProgressIndicator();
},
);
}
}
這里主要使用了 DefaultAssetBundle.of() 獲取 AssetBundle,然后使用 FutureBuilder 組件顯示異步數(shù)據(jù)。
加載圖片
Flutter 中使用 AssetImage 組件展示圖片。Flutter 會根據(jù)當(dāng)前設(shè)備的分辨率加載對應(yīng)的圖片,我們只需要按照特定的目錄結(jié)構(gòu)來放置圖片,例如:
assets
├── images
├── wechat.png
├── 2.0x
├── wechat.png
├── 3.0x
├── wechat.png
使用時:
new Image.asset("assets/images/wechat.png")
// or
new Image(
image: new AssetImage("assets/images/wechat.png"),
),
加載字體
下載字體并在 pubspec.yaml 中配置,這里的配置方式和前面有一點區(qū)別:
fonts:
- family: Charmonman
fonts:
- asset: assets/fonts/Charmonman-Regular.ttf
- asset: assets/fonts/Charmonman-Bold.ttf
weight: 500
其中 weight 屬性指定字體的粗細(xì),對應(yīng) TextStyle 的 fontWeight 屬性,會匹配對應(yīng)的字體。同理還有 style 屬性,對應(yīng)的值為 italic 和 normal。
使用時,通過 TextStyle 指定對應(yīng)的字體即可:
new Text(
"A red flair silhouetted the jagged edge of a wing.",
style: new TextStyle(
fontFamily: "Charmonman",
fontSize: 17.0,
fontWeight: FontWeight.w500,
),
)
使用字體圖標(biāo)
字體圖標(biāo)的使用和普通字體使用沒太大區(qū)別,只是文本內(nèi)容使用對應(yīng)圖標(biāo)的 Unicode 碼點即可:
new Text(
"\u{e7d7}",
style: new TextStyle(
fontFamily: "Iconfont",
fontSize: 36.0,
),
),