在 App 中會經常遇到需要從後臺拉取圖片的場景,這一方面會給伺服器帶來網路頻寬消耗,另一方面載入圖片的等待過程也會影響使用者體驗。因此,往往會在 App 端對圖片做快取機制,以避免同一張圖片反覆發起請求。在 Flutter 中,cached_image_network 即提供了快取網路圖片功能,同時還提供了豐富的載入過程指示。
上一篇Flutter 入門與實戰(六):給列表增加下拉重新整理和上滑載入更多功能,我們使用了列表,其中列表中有從網路下載圖片。直接使用 Flutter 自帶的 Image.network 下載圖片一是無法快取,二是體驗不夠好。熟悉 iOS 的肯定知道 SDWebImage,即 Objective-C 上用得最廣泛的圖片快取開源元件。與 SDWebImage 類似,Flutter 的 cached_image_network 外掛也實現了這樣的功能。cached_image_network 使用十分簡單,首先在 pubspec.yaml 中新增依賴:
dependencies:
flutter:
sdk: flutter
# ...其他依賴
cached_network_image: ^3.0.0
複製程式碼
之後在需要使用 cached_image_network 的地方引入原始碼:
import 'package:cached_network_image/cached_network_image.dart';
複製程式碼
最後在需要載入網路圖片的地方使用cached_image_network 替代原有的圖片載入方式(如 Image.network):
CachedNetworkImage(imageUrl: "http://via.placeholder.com/350x150"),
複製程式碼
以上是 cached_image_network 最簡單的用法,當然為了使用者體驗更好,推薦是使用佔點陣圖或載入指示器的方式提示使用者圖片正在載入。
使用佔點陣圖
CachedNetworkImage 提供了佔點陣圖和載入失敗後的錯誤指示的方法用於靜態指示。我們分別準備 image-default.png 和 image-failed.png 檔案表示預設佔點陣圖和載入失敗後的佔點陣圖,然後用 CachedNetworkImage 構造方法的 placeholder 和 errorWidget 來使用佔點陣圖,如下所示:
Widget _imageWrapper(String imageUrl) {
return SizedBox(
width: 150,
height: ITEM_HEIGHT,
child: CachedNetworkImage(
imageUrl: imageUrl,
placeholder: (context, url) => Image.asset('images/image-default.png'),
errorWidget: (context, url, error) =>
Image.asset('images/image-failed.png'),
),
);
}
}
複製程式碼
使用進度載入指示
也可以使用進度載入指示器來指示載入進度,載入進度指示支援原型進度和線型進度。這種對於大圖預覽時會更為常用,程式碼如下所示,其中LinearProgressIndicator是線型指示器,CircularProgressIndicator 是圓形指示器:
Widget _imageWrapper(String imageUrl) {
return SizedBox(
width: 150,
height: ITEM_HEIGHT,
child: CachedNetworkImage(
imageUrl: imageUrl,
progressIndicatorBuilder: (context, url, downloadProgress) =>
LinearProgressIndicator(value: downloadProgress.progress),
errorWidget: (context, url, error) =>
Image.asset('images/image-failed.png'),
),
);
}
複製程式碼
效果
效果如下圖所示,下拉重新整理後,可以先看到佔點陣圖,然後逐漸過渡到載入成功的圖片。如果修改連結為一個非法連結或資源不存在的連結,則會顯示圖片載入失敗的佔點陣圖。這種體驗相比空白沒有任何指示的 Image.network好很多。