インドネシアのPT.AQ Business Consulting IndonesiaでFlutterのエンジニア兼アドバイザーをしております菊池と申します。
Zennで本を出版しておりますflutter chips(30,000字程度)
Shimmerとは
データの読み込み中であることをユーザーに伝える方法の一つとして、読み込み中のコンテンツの形状に近似したUIの上に、グレー等の色でローディング状態を表現するアニメーションです。
以下、Flutter公式から参照。
実際の作成物
今回、私は実際に表示しているリストに合わせた以下のShimmerを作成いたしました。
導入手順
Shimmerプラグインのダウンロード
以下をpubspec.yamlに追加
pubspec.yaml
shimmer:
ベースファイル
ベースとなる以下のファイルを作成。
私の場合は、ほぼすべてのアプリに以下のファイルをUtilフォルダ配下に作成しています。
utils/shimmer.dart
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:shimmer/shimmer.dart';
class ShimmerWidget extends StatelessWidget {
final double width;
final double height;
final ShapeBorder shapeBorder;
const ShimmerWidget.rectangular({
this.width = double.infinity,
required this.height,
}) : this.shapeBorder = const RoundedRectangleBorder();
const ShimmerWidget.circular({
required this.width,
required this.height,
this.shapeBorder = const CircleBorder()
});
@override
Widget build(BuildContext context) => Shimmer.fromColors(
baseColor: Colors.grey[400]!,
highlightColor: Colors.grey[300]!,
child: Container(
height: height,
width: width,
decoration: ShapeDecoration(
color: Colors.grey[400],
shape: shapeBorder
),
),
);
}
使用方法
長方形のShimmer
ShimmerWidget.rectangular(height: 16)
楕円形のShimmer
ShimmerWidget.circular(width: 100, height: 36,
shapeBorder: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(36/2)
),
),
実際のShimmerのリストファイル
class ShimmerSeatListView extends StatelessWidget {
const ShimmerSeatListView({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.all(SizeConfig.smallMargin),
child: Container(
child: Card(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(SizeConfig.mediumSmallMargin),
),
color: ColorName.white,
elevation: 8,
child: Row(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Expanded(
child: ListTile(
title: ShimmerWidget.rectangular(height: 20),
subtitle: Padding(
padding: EdgeInsets.all(SizeConfig.smallestMargin),
child: Column(
children: [
ShimmerWidget.rectangular(height: 16),
SizedBox(height: SizeConfig.smallestMargin),
ShimmerWidget.rectangular(height: 16),
],
),
),
),
),
Padding(
padding: const EdgeInsets.all(SizeConfig.mediumMargin),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
ShimmerWidget.circular(width: 100, height: 36,
shapeBorder: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(36/2)
),
),
SizedBox(height: SizeConfig.smallMargin),
ShimmerWidget.rectangular(height: 24, width: 60),
],
),
)
],
),
),
),
);
}
}
参考文献