[Flutter] Shimmer - ListView Loading 화면을 개선해보자
Shimmer
ListView, GridView와 같은 위젯에 비동기 데이터를 보여주는데 있어서 UI 부분에 좀 더 부드럽게 보여주는 라이브러리이다.
비동기데이터에 대해서 Loading image를 보여주는 방식으로 많이 사용했었는데 요즘 대부분의 웹사이트 혹은 앱에서 이방식을 많이 볼수있다.
공식사이트의 Cookbook에서는 가이드를 제공하지만 그래도 library를 사용하는게 좀 더 편한거같다.
- Shimmer에 대한 가이드 : https://docs.flutter.dev/cookbook/effects/shimmer-loading
Pub dev Link :
https://pub.dev/packages/shimmer
shimmer | Flutter Package
A package provides an easy way to add shimmer effect in Flutter project
pub.dev
이와 비슷하게 skeleton library도 있다.
library를 사용할때 likes 숫자로 비교하게되어서 Shimmer를 사용하게 되었다.
Pub dev Link:
https://pub.dev/packages/skeletons
skeletons | Flutter Package
A Flutter package for building custom skeleton widgets to mimic the page's layout while loading.
pub.dev
![]() |
![]() |
How to use
사용법은 매우 간단하다.
List에 보일 항목에 맞춰서 shimmer ui를 작성해주고, data가 loading되면 다시 List의 UI를 보여주면 된다.
아래와 같이 pubspec.yaml 파일에 추가한다.
dependencies:
shimmer: ^2.0.0
이후 Android studio에서 pub get을 수행하거나 Command 명령어를 수행한다.
$ flutter pub get
다음 import 후에 다음과 같이 코드에서 사용하면 된다.
import 'package:flutter/material.dart';
import 'package:shimmer/shimmer.dart';
void main() => runApp(const MyApp());
class MyApp extends StatefulWidget
{
const MyApp({Key? key}) : super(key: key);
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State {
List products = ["data1", "data2", "data3", "data4", "data5"];
@override
Widget build(BuildContext context) {
return const MaterialApp(
debugShowCheckedModeBanner: false,
home: ShimmerLoaderExample(),
);
}
}
class ShimmerLoaderExample extends StatelessWidget {
const ShimmerLoaderExample({
super.key,
});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text("Shimmer loader"),
),
body: Padding(
padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SizedBox(
height: 200,
width: double.infinity,
child: ClipRRect(
borderRadius: BorderRadius.circular(16),
child: Image.network(
'https://picsum.photos/250?image=9',
fit: BoxFit.cover,
loadingBuilder: (context, child, loadingProgress) =>
Shimmer.fromColors(
baseColor: Colors.grey[300]!,
highlightColor: Colors.white,
child: Container(
color: Colors.grey,
),
),
),
),
),
],
),
),
);
}
}