Flutterアプリで画像を表示する際にロード画面を表示する方法です。
画像の表示 with ロード画面
Flutterアプリで画像を表示する方法は以前のブログで紹介しましたが、
インターネットの画像を表示する場合、少なからずダウンロードの時間が発生します。
ユーザーからすると画面にいきなり画像が表示されるので、あまりよろしくありません。
それを解決するために、画像のダウンロード中はローディングを表示(PlaceHolder)して、
ユーザーへ「今はロード中ですよ、ちょっと待ってね」と伝えることにしましょう。
FadeInImageを使う
FadeInImageを使えば簡単に実装することができます。
FadeInImage.assetNetwork( placeholder: 'images/loading.gif', image: 'https://foo.png', );
placeholder
にはassetsの画像を指定します。
gif画像も可能ですので、ローディングgif画像なら「動いている感」をユーザーに与えられますね。
image
にはダウンロード先のURLを指定します。
FadeInImageにはassetNetwork
とmemoryNetwork
の関数があり、memoryの場合はUint8List
で指定します。
コード全体
import 'package:flutter/material.dart'; class MyImageFadeinPage extends StatefulWidget { MyImageFadeinPage({Key key, this.title}) : super(key: key); final String title; @override _MyImageFadeinPageState createState() => _MyImageFadeinPageState(); } class _MyImageFadeinPageState extends State<MyImageFadeinPage> { @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text(widget.title), ), body: Column(children: <Widget>[ Container( child: FadeInImage.assetNetwork( height: 400, placeholder: 'images/loading.gif', image: 'https://cdn-ak.f.st-hatena.com/images/fotolife/h/hisurga/20190616/20190616231036.png', ), ), Center( child: Text('Bottom Text'), ), ]), ); } }
CachedNetworkImageを使う
FadeInImageは便利ですが、ローディングはassetやmemoryで用意しなければいけません。
CachedNetworkImageならplaceholderにウィジェットを配置することができます。
cached_network_image | Flutter Package
さらには、失敗時画面の用意もキャッシュの利用も簡単にできます。
(あえてキャッシュを利用したくない場合のオプションは用意されていないようです)
外部プラグインですが、公式のcookbookでも紹介されています。
pubspec.yamlの編集
pubspec.yamlにcached_network_image
を追加します。
dependencies: flutter: sdk: flutter cupertino_icons: ^0.1.2 cached_network_image: "^0.4.0"
placeholderとerrorWidgetの配置
placeholder
とerrorWidget
にはウィジェットを配置できるので、CircularProgressIndicator
やTextなどを配置することができます。
CachedNetworkImage( imageUrl: "http://foo.png", placeholder: CircularProgressIndicator(), errorWidget: Icon(Icons.error), ),
ダウンロード成功時
失敗時
コード全体
import 'package:flutter/material.dart'; import 'package:cached_network_image/cached_network_image.dart'; class MyImageCachednetworkPage extends StatefulWidget { MyImageCachednetworkPage({Key key, this.title}) : super(key: key); final String title; @override _MyImageCachednetworkPageState createState() => _MyImageCachednetworkPageState(); } class _MyImageCachednetworkPageState extends State<MyImageCachednetworkPage> { @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text(widget.title), ), body: Column(children: <Widget>[ Container( height: 400, child: CachedNetworkImage( imageUrl: "https://cdn-ak.f.st-hatena.com/images/fotolife/h/hisurga/20190616/20190616231036.png", placeholder: Center( child: CircularProgressIndicator(), ), errorWidget: Center( child: Icon(Icons.error), ), ), ), Center( child: Text('Bottom Text'), ), ]), ); } }
プロジェクトの全体像はGitHubに載せています。
参考にさせていただいたサイト
Fade in images with a placeholder - Flutter
FadeInImage class - widgets library - Dart API