LoginSignup
0
0

Flutterの画像読み込み中の表示をイイ感じにしよう!

Last updated at Posted at 2024-02-09

この記事を読んでほしい人

FLutterの画像読み込みで「くるくる🌀」させてる人

やること

  • cached_network_imageで画像をキャッシュして表示する
  • skelton_textで画像読み込み時にキラッ✨とさせる
  • (おまけ)lottieでイイ感じのアニメーションをつける

これらのパッケージはインストールしておいてください!

動作イメージ
ZennのRss Feedを取得して表示しています(アニメーションをしっかり表示するために3秒間待っています)
https://youtu.be/zEpzqLV-0B8

サンプルリポジトリ公開しています!
https://github.com/Taichiro-S/flutter_image_loading_sample

環境・バージョン等

macOS Sonoma 14.1.1
iOS(Simulator) 17.0
Xcode 15.0.1
Dart SDK 3.2.2
Flutter 3.16.2

画像読み込み時にキラッ✨とさせる

cached_network_image で画像(本サンプルではZennのRss Feedのenclosure)を表示します

SizedBox(
    width: MediaQuery.of(context).size.width,
    child: article.enclosureUrl != ''
        ? CachedNetworkImage(
            imageUrl: article.enclosureUrl,
            placeholder: (context, url) => SkeltonContainerWidget(
                width: MediaQuery.of(context).size.width),
            errorWidget: (context, url, error) =>
                const Image(image: AssetImage('assets/no_image.png')))
        : const Image(image: AssetImage('assets/no_image.png')),
)

placeholder に SkeltonAnimationを設定します
height, width等を表示する画像に合わせて調節してください

import 'package:flutter/material.dart';
import 'package:skeleton_text/skeleton_text.dart';

class SkeltonContainerWidget extends StatelessWidget {
  const SkeltonContainerWidget({
    super.key,
    required this.width,
  });
  final double width;
  @override
  Widget build(BuildContext context) {
    return SkeletonAnimation(
        child: Padding(
            padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 10),
            child: Container(
              width: width,
              height: 180,
              decoration: BoxDecoration(
                  color: Colors.grey[300],
                  borderRadius: BorderRadius.circular(10)),
            )));
  }
}

イイ感じのアニメーションをつける

ここからよさげなのをjson形式でダウンロードします
サンプルで使用させていただいたのはこちらです

ダウンロードしたjsonをloading.jsonとしてassetsフォルダに入れ、pubspec.ymlに以下のように追記します

flutter:
  assets:
  - assets/loading.json

あとはloading時に呼び出すだけです!
以下ではRiverpodのAsyncValue.whenloading内で表示しています

import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:lottie/lottie.dart';

class RssFeedPage extends ConsumerWidget {
  const RssFeedPage({super.key});
  @override
  Widget build(BuildContext context, WidgetRef ref) {
    final selectedTopic = ref.watch(topicProvider);
    final articlesAsync = ref.watch(articlesProvider(topic: selectedTopic));
    return DefaultTabController(
        length: topics.length,
        child: Scaffold(
            // 略
            body: articlesAsync.when(
                loading: () => Lottie.asset('assets/loading.json'),
                error: (error, stackTrace) =>
                    Center(child: Text(error.toString())),
                data: (articles) {
                  // 略
                })));
  }
}

参考にさせていただいた記事

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0