Flutter

[Flutter] Shimmer - ListView Loading 화면을 개선해보자

코다루 2023. 1. 3. 00:01
728x90
반응형

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,
                    ),
                  ),
                ),
              ),
            ),
          ],
        ),
      ),
    );
  }
}

 

 

728x90
반응형