상세 컨텐츠

본문 제목

Sliver와 애니메이션을 결합한 고급 패턴

공부/Flutter

by micalcomanie 2025. 1. 1. 17:27

본문

728x90
반응형
SMALL

Flutter의 Sliver는 애니메이션과 결합하여 고급스럽고 생동감 있는 사용자 경험을 제공합니다.
이 글에서는 Sliver와 애니메이션을 활용해 구현할 수 있는 고급 패턴들을 소개합니다.


1. 고급 패턴 1: 스크롤 위치에 따른 애니메이션 효과

스크롤 위치를 감지하여 특정 위젯의 애니메이션을 동적으로 변경합니다.

코드 예제

import 'package:flutter/material.dart';

class ScrollAnimatedSliver extends StatefulWidget {
  @override
  _ScrollAnimatedSliverState createState() => _ScrollAnimatedSliverState();
}

class _ScrollAnimatedSliverState extends State<ScrollAnimatedSliver> {
  final ScrollController _scrollController = ScrollController();
  double _scale = 1.0;

  @override
  void initState() {
    super.initState();
    _scrollController.addListener(_updateScale);
  }

  void _updateScale() {
    setState(() {
      _scale = 1 - (_scrollController.offset / 300).clamp(0.0, 1.0);
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: CustomScrollView(
        controller: _scrollController,
        slivers: [
          SliverAppBar(
            expandedHeight: 300.0,
            flexibleSpace: FlexibleSpaceBar(
              title: Text('Scroll Animation'),
            ),
          ),
          SliverToBoxAdapter(
            child: AnimatedScale(
              scale: _scale,
              duration: Duration(milliseconds: 300),
              child: Container(
                height: 200.0,
                color: Colors.amber,
                child: Center(
                  child: Text('Scaling Box', style: TextStyle(fontSize: 24.0)),
                ),
              ),
            ),
          ),
          SliverList(
            delegate: SliverChildBuilderDelegate(
              (context, index) => ListTile(title: Text('Item $index')),
              childCount: 20,
            ),
          ),
        ],
      ),
    );
  }

  @override
  void dispose() {
    _scrollController.dispose();
    super.dispose();
  }
}

2. 고급 패턴 2: Parallax 애니메이션

SliverAppBar와 함께 Parallax 효과를 추가하여 스크롤 시 배경이 느리게 이동하는 효과를 만듭니다.

코드 예제

SliverAppBar(
  expandedHeight: 250.0,
  flexibleSpace: FlexibleSpaceBar(
    background: Stack(
      fit: StackFit.expand,
      children: [
        Positioned.fill(
          child: Image.network(
            'https://example.com/image.jpg',
            fit: BoxFit.cover,
          ),
        ),
        Positioned(
          bottom: 20.0,
          left: 20.0,
          child: Text(
            'Parallax Effect',
            style: TextStyle(color: Colors.white, fontSize: 24.0),
          ),
        ),
      ],
    ),
  ),
)

3. 고급 패턴 3: 섹션 기반 애니메이션

스크롤 섹션별로 개별 애니메이션을 적용하여 사용자의 인터랙션을 강화합니다.

코드 예제

class SectionAnimatedSliver extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: CustomScrollView(
        slivers: [
          SliverPersistentHeader(
            pinned: true,
            delegate: _AnimatedHeaderDelegate(),
          ),
          SliverList(
            delegate: SliverChildBuilderDelegate(
              (context, index) => ListTile(
                title: Text('Section Item $index'),
              ),
              childCount: 10,
            ),
          ),
          SliverToBoxAdapter(
            child: AnimatedOpacity(
              opacity: 1.0,
              duration: Duration(milliseconds: 500),
              child: Container(
                height: 200.0,
                color: Colors.blue,
                child: Center(
                  child: Text('Animated Section', style: TextStyle(color: Colors.white, fontSize: 24.0)),
                ),
              ),
            ),
          ),
        ],
      ),
    );
  }
}

class _AnimatedHeaderDelegate extends SliverPersistentHeaderDelegate {
  @override
  Widget build(BuildContext context, double shrinkOffset, bool overlapsContent) {
    return Container(
      color: Colors.red,
      child: Center(
        child: Text(
          'Sticky Header',
          style: TextStyle(color: Colors.white, fontSize: 20.0),
        ),
      ),
    );
  }

  @override
  double get maxExtent => 100.0;

  @override
  double get minExtent => 50.0;

  @override
  bool shouldRebuild(SliverPersistentHeaderDelegate oldDelegate) => true;
}

4. 실습: 전체 화면에 애니메이션 적용

CustomScrollView와 다양한 Sliver 위젯을 결합하여 완성도 높은 애니메이션 UI를 구현합니다.

주요 기능

  1. 스크롤에 따른 색상 변화
  2. Parallax 배경
  3. 섹션별 애니메이션

코드 예제

import 'package:flutter/material.dart';

class FullScreenAnimatedSliver extends StatefulWidget {
  @override
  _FullScreenAnimatedSliverState createState() =>
      _FullScreenAnimatedSliverState();
}

class _FullScreenAnimatedSliverState extends State<FullScreenAnimatedSliver> {
  final List<bool> _expandedStates = List.generate(20, (_) => false);

  void _toggleExpand(int index) {
    setState(() {
      _expandedStates[index] = !_expandedStates[index];
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: CustomScrollView(
        slivers: [
          SliverAppBar(
            expandedHeight: 300.0,
            flexibleSpace: FlexibleSpaceBar(
              title: Text('Full Screen Animation'),
              background: Image.network(
                'https://via.placeholder.com/800x400',
                fit: BoxFit.cover,
              ),
            ),
          ),
          SliverList(
            delegate: SliverChildBuilderDelegate(
                  (context, index) => GestureDetector(
                onTap: () => _toggleExpand(index),
                child: AnimatedContainer(
                  duration: Duration(milliseconds: 300),
                  color: index.isEven ? Colors.amber : Colors.green,
                  height: _expandedStates[index] ? 200.0 : 100.0,
                  child: Center(
                    child: Text(
                      'Item $index',
                      style: TextStyle(fontSize: 20.0, color: Colors.white),
                    ),
                  ),
                ),
              ),
              childCount: _expandedStates.length,
            ),
          ),
        ],
      ),
    );
  }
}

void main() => runApp(MaterialApp(home: FullScreenAnimatedSliver()));

5. 결론

Sliver와 애니메이션을 결합하면 사용자 경험을 혁신적으로 개선할 수 있습니다. 이번 글에서 다룬 고급 패턴을 활용하여 창의적이고 역동적인 UI를 만들어 보세요. 다음 글에서는 Sliver와 애니메이션을 활용한 사용자 인터랙션 최적화 방법을 다룰 예정입니다.


참고 자료

728x90
반응형
LIST

관련글 더보기