來吧!Flutter(11) — 初探 Image
圖片,是 App 中最常出現的 Widget 之一,依來源分類可分為兩種:本機圖片、網路圖片。針對兩種圖片來源 Flutter 都能使用 Image Widget 來處理它們。
本機圖片
介紹如何使用本機圖片之前,我們需要了解 Flutter 的 assets 系統。
assets
在 pubspec.yaml 檔案中,我們可以加上
flutter:
assets:
- assets\good_morning.png
- assets\good_night.png
這代表什麼意思呢?
我們將兩張存放於 assets 資料夾的圖片,分別為 good_morning.png 以及 good_night.png 加入至系統中,於是我們就可以在程式中呼叫這兩張圖片。
呼叫方法
Image(image: AssetImage('asset image path'));或是Image.asset('asset image path')
其中,Image 建構子的 image 屬性代入的是 ImageProvider,因為我們需要顯示存放在 asset 裡面的圖檔,所以這邊使用 AssetImage 代入。
Flutter 針對 asset image 提供了另一個建構子 Image.asset,我們只需要將 asset 的路徑代入即可。AssetImage 已經被包在 Image.asset 中。
AssetImage 類
在 App 開發中,我們常常會根據不同裝置解析度來使用不同大小的圖片,Flutter 的 AssetImage 類也提供了相同的功能。
在 asset 的資料夾中,我們可以根據不同的像素密度 (Pixel Densities) 來擺放相關的圖片。 例如:
good_morning.png
1.5x/good_morning.png
2.0x/good_morning.pnggood_night.png
1.5x/good_night.png
2.0x/good_morning.png
Android 開發者可能不太熟悉像素密度的倍數,一般我們都是以 MDPI、HDMI、XHDPI… 代表,
換算值,我們可以參考下圖,
網路圖片
除了來自 assets 的圖片外,Image 類 也可以支援網路圖片
假設有一張來自網路的圖片,網址如下
https://cdn.pixabay.com/photo/2015/07/11/23/02/plane-841441_960_720.jpg
我們要如何顯示網路圖片呢?
Image(image: NetworkImage('Image URI'));或Image.network('Image URI')
其中,NetworkImage 也是 ImageProvider 的類別之一。
同時,Image 也提供了 Image.network 建構子,將 NetworkImage 包在其中。
但是,如果圖片下載比較慢,或是沒有網路,那麼圖片就會顯示空白。
要怎麼做呢?
在 Image 以及 Image.network 中皆含有一個名為 loadingBuilder 的屬性,我們可以在 loadingBuilder 中增加當圖片尚未完全下載時,應該顯示什麼。如下:
- loadingBuilder 的型別是 ImageLoadingBuilder,其建構子如下
typedef ImageLoadingBuilder = Widget Function(
BuildContext context,
Widget child,
ImageChunkEvent loadingProgress,
);
這邊可以看到 ImageLoadingBuilder 前方的關鍵字 typedef,表示這是函數類型的別名。在 Dart 中一般用在定義 callback 的介面 (interface), loadingBuilder 被呼叫時,會代入三個參數。
其中,Widget 就是這個 Image,而 ImageChunkEvent 則是每一次呼叫 loadingBuilder 帶進來下載的資訊。
ImageChunkEvent 裡面有兩個屬性:cumulativeBytesLoaded 以及 expectedTotalBytes。
一個是累積下載量,另一個則是預期下載量。
最後,當下載完成時,ImageChunkEvent 為 null。
frameBuilder
除了 loadingBuilder 以外,Image class 還提供了 frameBuilder。frameBuilder 可以在下載完成之後,繪製動畫。如下:
小結
在 Image 類中,提供不同的 ImageProvider 處理不同的圖片來源使用,如本篇文章的本機圖片及網路圖片 。
使用本機圖片時,我們可以針對不同的像素密度,來使用不同大小的圖片,我們只要在 asset 資料夾下分別將不同像素密度的圖片放在相對應的資料夾中,Flutter 即可自動尋找適當的圖片。
另外,我們還可以使用 loadingBuilder 或是 frameBuilder 在圖片讀取的時候,做轉場的效果。
Image 類除了提供 Image.asset、Image.network 這兩個本篇文章所介紹的建構子外,還有 Image.file 以及 Image.memory,我們將在後面的文章繼續討論這兩個 Image的建構子。
如果這篇文章有幫助到你,別忘了幫我拍拍手。
謝謝
參考
Flutter — Adding assets and images
Flutter — loadingBuilder
Flutter — frameBuilder
Android — Screen Densities