[flutter] 플러터 sticky 헤더를 가진 이미지 갤러리 만들기

플러터(Flutter)로 이미지 갤러리를 만드는 것은 매우 흥미로운 작업입니다. 하지만 간단한 이미지 갤러리에서는 한 가지 문제가 있을 수 있습니다. 사용자가 많은 이미지를 포함하는 갤러리를 스크롤할 때, 상단의 헤더가 사라지는 것입니다. 이는 사용자 경험을 저하시킬 수 있습니다.

이 문제를 해결하기 위해 Sticky 헤더를 가진 이미지 갤러리를 만들어 보겠습니다. 이렇게하면 사용자가 어떤 이미지를 스크롤하더라도 헤더가 항상 보이게 됩니다.

필요한 패키지 설치

먼저 flutter_sticky_header 패키지를 설치해야 합니다. 이 패키지를 사용하면 Sticky 헤더를 쉽게 구현할 수 있습니다.

dependencies:
  flutter_sticky_header: ^0.4.0

코드 구현

간단한 이미지 갤러리 앱을 만들기 위해 다음 단계를 따르세요.

  1. pubspec.yaml 파일에 flutter_sticky_header 패키지를 추가합니다.

  2. main.dart 파일을 열고 필요한 패키지를 import합니다.

import 'package:flutter/material.dart';
import 'package:flutter_sticky_header/flutter_sticky_header.dart';
  1. 이제 StatelessWidget을 확장한 MyApp 클래스를 만듭니다.
class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Sticky Header Gallery',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: GalleryPage(),
    );
  }
}
  1. 그리고 GalleryPage 클래스를 만듭니다.
class GalleryPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Sticky Header Gallery'),
      ),
      body: CustomScrollView(
        slivers: <Widget>[
          _buildHeader(context),
          _buildImageGrid(context),
        ],
      ),
    );
  }

  SliverPersistentHeader _buildHeader(BuildContext context) {
    return SliverPersistentHeader(
      pinned: true,
      delegate: StickyHeaderDelegate(
        minHeight: 60.0,
        maxHeight: 200.0,
        child: Container(
          color: Colors.blue,
          child: Center(
            child: Text(
              'Header',
              style: TextStyle(
                color: Colors.white,
                fontSize: 24,
                fontWeight: FontWeight.bold,
              ),
            ),
          ),
        ),
      ),
    );
  }

  Widget _buildImageGrid(BuildContext context) {
    return SliverGrid(
      gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
        crossAxisCount: 3,
        mainAxisSpacing: 10.0,
        crossAxisSpacing: 10.0,
        childAspectRatio: 1.0,
      ),
      delegate: SliverChildBuilderDelegate(
        (BuildContext context, int index) {
          return Container(
            color: Colors.grey,
            child: Image.network(
              'https://example.com/image_$index.jpg',
              fit: BoxFit.cover,
            ),
          );
        },
        childCount: 20,
      ),
    );
  }
}
  1. 마지막으로 StickyHeaderDelegate 클래스를 구현합니다.
class StickyHeaderDelegate extends SliverPersistentHeaderDelegate {
  final double minHeight;
  final double maxHeight;
  final Widget child;

  StickyHeaderDelegate({
    required this.minHeight,
    required this.maxHeight,
    required this.child,
  });

  @override
  double get minExtent => minHeight;

  @override
  double get maxExtent => maxHeight;

  @override
  Widget build(BuildContext context, double shrinkOffset, bool overlapsContent) {
    return SizedBox.expand(child: child);
  }

  @override
  bool shouldRebuild(covariant StickyHeaderDelegate oldDelegate) {
    return maxHeight != oldDelegate.maxHeight ||
        minHeight != oldDelegate.minHeight ||
        child != oldDelegate.child;
  }
}

실행

모든 코드를 작성한 후 앱을 실행해보세요. 스크롤을 통해 이미지 갤러리를 확인할 때 상단에 고정된 헤더가 있는 것을 확인할 수 있습니다.

이제 플러터에서 Sticky 헤더를 가진 이미지 갤러리를 만들기 위한 기본적인 개념 및 코드를 알게 되었습니다.

참고 자료