在開發(fā)Flutter APK
時,我們可以將一些資源預(yù)置在APP
中胖烛,這些資源可以分為以下幾類:
- 文本
- 圖片
為了統(tǒng)一管理眼姐,我們將它們統(tǒng)一放在assets/
目錄下诅迷,然后介紹一下如何對它們進行讀取。
一众旗、文本
文本一般用于存儲默認數(shù)據(jù)罢杉,在第一次進入無網(wǎng)的情況下進行數(shù)據(jù)的展示。
在pubspec.yaml
的flutter
標(biāo)簽下贡歧,聲明要加載的文件名:
flutter:
assets :
- assets/files/hello.txt
文本的加載有兩種方式:
- 使用全局的靜態(tài)
rootBundle
對象滩租,需要導(dǎo)入package:flutter/services.dart
,好處是不需要提供BuildContext
艘款。 - 使用
DefaultAssetBundle
獲取當(dāng)前BuildContext
的AssetBundle
來加載持际。
兩種方式的示例代碼如下,分別對應(yīng)于_loadAssetFile()
和_loadAssetFile2()
:
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
void main() => runApp(AssetDemo());
class AssetDemo extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: Text('Assets Demo')),
body: AssetFilesWidget(),
),
);
}
}
class AssetFilesWidget extends StatefulWidget {
@override
State<StatefulWidget> createState() {
return _AssetFilesWidgetState();
}
}
class _AssetFilesWidgetState extends State<AssetFilesWidget> {
String text;
@override
void initState() {
super.initState();
_loadAssetFile2();
}
@override
Widget build(BuildContext context) {
return Text(text ?? 'default');
}
_loadAssetFile() async {
String text = await rootBundle.loadString('assets/files/hello.txt');
print(text);
setState(() {
this.text = text;
});
}
_loadAssetFile2() async {
String text = await DefaultAssetBundle.of(context).loadString('assets/files/hello.txt');
setState(() {
this.text = text;
});
}
}
二哗咆、圖片
圖片的加載和文本類似蜘欲,也是需要先進行聲明再使用。
在Android
中晌柬,我們會將圖片放在res/
下對應(yīng)的drawable-?
文件夾中姥份,而放在不同的文件夾中,根據(jù)設(shè)備dpi
(每英寸圖片上點的個數(shù))的不同年碘,最終加載到內(nèi)存中的圖片大小是不一樣的澈歉,在Flutter
中也有類似的概念。
關(guān)于Android
中相關(guān)的概念可以查看這篇文章 圖片基礎(chǔ)知識梳理(2) - Bitmap 占用內(nèi)存分析屿衅。
在Flutter
中埃难,也有和drawable-?
相同的設(shè)計,用N.X
來代替:
其加載的邏輯為:
- 根目錄默認對應(yīng)于
1.0
分辨率的圖片涤久。 - 設(shè)備在選擇圖片時涡尘,將會選擇離它
dpiDensity
最近的文件夾。假如dpiDensity=1.8
响迂,那么會選擇2.0x
目錄下的資源考抄。(dpiDensity
用MediaQuery.of(context).devicePixelRatio
來獲取。) - 確定了需要選擇哪個文件夾的圖片后蔗彤,假如沒有設(shè)置
Image Widget
控件的大小川梅,那么最終加載顯示的寬高還要用原始圖片寬高再除以對應(yīng)文件夾的系數(shù)。
示例如下:
在pubspec.yaml
中聲明:
flutter:
uses-material-design: true
assets :
- assets/files/hello.txt
- assets/images/
使用Image(key : imageKey, image : AssetImage('assets/images/pic.png'))
加載圖片然遏。
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
void main() => runApp(AssetDemo());
class AssetDemo extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: Text('Assets Demo')),
body: AssetImageWidget(),
),
);
}
}
class AssetImageWidget extends StatefulWidget {
@override
State<StatefulWidget> createState() {
return _AssetImageWidgetState();
}
}
class _AssetImageWidgetState extends State<AssetImageWidget> {
String text;
GlobalKey imageKey = new GlobalKey();
@override
Widget build(BuildContext context) {
return Column(children: <Widget>[
RaisedButton(onPressed: () {
text = 'height=${imageKey.currentContext.size.height}'
',width=${imageKey.currentContext.size.height}'
',dpi=${MediaQuery.of(context).devicePixelRatio}';
print(text);
}, child: Text('refresh')),
Image(key : imageKey, image : AssetImage('assets/images/pic.png'))
]);
}
}
為了驗證之前的加載邏輯贫途,試驗了以下三種情況:
- 在主資源
assets/images
目錄下添加pic.png
,結(jié)果為:
height=96.0,width=96.0,dpi=3.0
- 在主資源和
assets/images/3.0x
目錄下添加pic.png
待侵,結(jié)果為:
height=32.0,width=32.0,dpi=3.0
- 在主資源和
assets/images/2.0x
目錄下添加pic.png
潮饱,結(jié)果為:
height=48.0,width=48.0,dpi=3.0
這里有點需要注意,當(dāng)我們改變資源目錄的結(jié)構(gòu)時诫给,需要修改pubspec.yaml
才能生效香拉。
三啦扬、使用第三方包中的圖片
3.1 應(yīng)用程序使用第三方包中的圖片
當(dāng)應(yīng)用程序依賴于包名為my_icons
的包,加載圖像的方式為:
AssetImage('icons/heart.png', package: 'my_icons')
3.2 打包第三方圖片
對于第三方包中的圖片凫碌,有以下幾種情況:
- 第三方包自己使用的資源扑毡,那么必須要在它自身的
pubspec.yaml
中聲明,并且使用的時候要帶上自己的包名盛险。 - 第三方包提供給其它人使用瞄摊,但自身不使用,分為兩種情況:
- 無論使用者是否用到都強制打包苦掘。這種情況下换帜,第三方包需要在它的
pubspec.yaml
中聲明,使用者則不需要鹤啡。 - 由使用者選擇是否打包惯驼。第三方包將資源放在
lib/
目錄下并且不在pubspec.yaml
中聲明,由使用者根據(jù)使用情況在它自己的pubspec.yaml
中聲明递瑰。
- 無論使用者是否用到都強制打包苦掘。這種情況下换帜,第三方包需要在它的
例如第三方包名為fancy_backgrounds
祟牲,它的資源有:
…/lib/backgrounds/background1.png
…/lib/backgrounds/background2.png
…/lib/backgrounds/background3.png
假如使用者希望使用background1
,那么就要在它自己的pubspec.yaml
中聲明抖部,注意這里省略了隱式的lib
目錄:
flutter:
assets:
- packages/fancy_backgrounds/backgrounds/background1.png