使用 cached_network_image 優化 Flutter 圖片加載

在 App 中會經常遇到需要從後臺拉取圖片的場景,這一方面會給服務器帶來網絡帶寬消耗,另一方面加載圖片的等待過程也會影響用戶體驗。因此,往往會在 App 端對圖片做緩存機制,以避免同一張圖片反覆發起請求。在 Flutter 中,cached_network_image 即提供了緩存網絡圖片功能,同時還提供了豐富的加載過程指示。

上一篇我們使用了列表,其中列表中有從網絡下載圖片。直接使用 Flutter 自帶的 Image.network 下載圖片一是無法緩存,二是體驗不夠好。熟悉 iOS 的肯定知道 SDWebImage,即 Objective-C 上用得最廣泛的圖片緩存開源組件。與 SDWebImage 類似,Flutter 的 cached_network_image 插件也實現了這樣的功能。cached_network_image 使用十分簡單,首先在 pubspec.yaml 中添加依賴:

dependencies:
  flutter:
    sdk: flutter

  # ...其他依賴
  cached_network_image: ^3.0.0

之後在需要使用 cached_network_image 的地方引入源碼:

import 'package:cached_network_image/cached_network_image.dart';

最後在需要加載網絡圖片的地方使用cached_network_image 替代原有的圖片加載方式(如 Image.network):

CachedNetworkImage(imageUrl: "http://via.placeholder.com/350x150"),

以上是 cached_network_image 最簡單的用法,當然爲了用戶體驗更好,推薦是使用佔位圖或加載指示器的方式提示用戶圖片正在加載。

使用佔位圖

CachedNetworkImage 提供了佔位圖和加載失敗後的錯誤指示的方法用於靜態指示。我們分別準備 image-default.png 和 image-failed.png 文件表示默認佔位圖和加載失敗後的佔位圖,然後用 CachedNetworkImage 構造方法的 placeholdererrorWidget 來使用佔位圖,如下所示:

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好很多。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章