OpenContainer

샤워실의 바보·2024년 4월 9일
0

Flutter Animation

목록 보기
29/31
post-thumbnail
import 'package:animations/animations.dart';
import 'package:flutter/material.dart';

class ContainerTransformScreen extends StatefulWidget {
  const ContainerTransformScreen({super.key});

  
  State<ContainerTransformScreen> createState() =>
      _ContainerTransformScreenState();
}

class _ContainerTransformScreenState extends State<ContainerTransformScreen> {
  bool _isGrid = false; // 그리드 뷰 상태를 토글하기 위한 변수

  void _toggleGrid() {
    setState(() {
      _isGrid = !_isGrid; // 그리드 뷰와 리스트 뷰 간 전환
    });
  }

  
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Container Transform'),
        actions: [
          IconButton(
            onPressed: _toggleGrid,
            icon: const Icon(Icons.grid_4x4), // 그리드 뷰로 전환하는 버튼
          )
        ],
      ),
      body: _isGrid
          ? GridView.builder(
              itemCount: 20,
              gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
                crossAxisCount: 2,
                mainAxisSpacing: 8,
                crossAxisSpacing: 8,
                childAspectRatio: 1 / 1.5,
              ),
              itemBuilder: (context, index) => OpenContainer(
                closedElevation: 0,
                openElevation: 0,
                closedBuilder: (context, action) => Column(
                  children: [
                    Image.asset("assets/covers/${(index % 5) + 1}.jpg"), // 표지 이미지
                    const Text('Dune Soundtrack'), // 앨범 제목
                    const Text(
                      'Hans Zimmer', // 아티스트 이름
                      style: TextStyle(
                        fontSize: 14,
                      ),
                    )
                  ],
                ),
                openBuilder: (context, action) =>
                    DetailScreen(image: (index % 5) + 1), // 상세 화면으로 전환
              ),
            )
          : ListView.separated(
              itemBuilder: (context, index) => OpenContainer(
                closedElevation: 0,
                openElevation: 0,
                openBuilder: (context, action) =>
                    DetailScreen(image: (index % 5) + 1), // 상세 화면으로 전환
                closedBuilder: (context, action) => ListTile(
                  leading: Container(
                    width: 50,
                    height: 50,
                    decoration: BoxDecoration(
                      shape: BoxShape.circle,
                      image: DecorationImage(
                        image: AssetImage(
                          "assets/covers/${(index % 5) + 1}.jpg", // 표지 이미지
                        ),
                      ),
                    ),
                  ),
                  title: const Text("Dune Soundtrack"), // 앨범 제목
                  subtitle: const Text("Hans Zimmer"), // 아티스트 이름
                  trailing: const Icon(
                    Icons.arrow_forward_ios, // 화살표 아이콘
                  ),
                ),
              ),
              separatorBuilder: (context, index) => const SizedBox(height: 20),
              itemCount: 20,
            ),
    );
  }
}

class DetailScreen extends StatelessWidget {
  final int image;

  const DetailScreen({
    super.key,
    required this.image,
  });

  
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text("Detail Screen"), // 상세 화면 제목
      ),
      body: Column(
        children: [
          Image.asset("assets/covers/$image.jpg"), // 선택된 이미지
          const Text(
            "Detail Screen", // 상세 화면 텍스트
            style: TextStyle(
              fontSize: 18,
            ),
          )
        ],
      ),
    );
  }
}

Flutter에서 OpenContainer 위젯은 animations 패키지의 일부로, 소스 컨테이너에서 대상 컨테이너로의 부드러운 전환을 제공하는 데 사용됩니다. 이는 사용자 인터페이스(UI)에 매력적인 애니메이션 효과를 추가하여, 앱의 전반적인 사용자 경험을 향상시키는 데 도움이 됩니다. OpenContainer를 사용하는 주된 목적은 하나의 화면에서 다른 화면으로 넘어갈 때, 또는 단일 위젯이 다른 위젯으로 변환될 때 매끄러운 시각적 전환을 제공하는 것입니다.

OpenContainer의 주요 속성:

  • closedBuilder: 컨테이너가 닫혀 있을 때(기본 상태) 보여줄 위젯을 정의합니다. 사용자가 이 위젯을 탭하면 openBuilder에 정의된 위젯으로 전환됩니다.
  • openBuilder: 컨테이너가 열려 있을 때(전환 후) 보여줄 위젯을 정의합니다. 이는 일반적으로 새로운 화면이나 상세 정보를 표시하는 데 사용됩니다.
  • closedElevation, openElevation: 각각 닫혀 있을 때와 열려 있을 때의 컨테이너 높이(그림자 깊이)를 설정합니다.
  • transitionDuration: 열리고 닫히는 애니메이션의 지속 시간을 설정합니다.

예제 설명:

위 코드에서는 ContainerTransformScreen이라는 StatefulWidget을 사용하여, 사용자가 그리드 뷰와 리스트 뷰 사이를 전환할 수 있도록 합니다. 이를 통해 OpenContainer 위젯의 사용법을 다양한 상황에서 보여줍니다.

  • 그리드 뷰: 여러 항목을 그리드 형식으로 보여주며, 각 항목을 탭하면 상세 화면으로의 부드러운 전환 애니메이션을 시작합니다.
  • 리스트 뷰: 항목들을 리스트 형태로 나열하며, 마찬가지로 항목을 탭할 때 상세 화면으로 전환됩니다.

각 항목은 OpenContainer 위젯을 사용하여 구현됩니다. closedBuilder는 메인 화면에서 사용자에게 보여지는 부분(이미지와 텍스트)을 정의하고, openBuilder는 사용자가 해당 항목을 탭했을 때 보여질 상세 화면을 정의합니다.

상세 화면 (DetailScreen):

DetailScreen은 사용자가 항목을 탭했을 때 나타나는 화면입니다. 이 화면에는 대형 이미지와 "Detail Screen"이라는 텍스트가 표시됩니다. 이 클래스는 image 매개변수를 필요로 하는데, 이는 각 항목에 대한 이미지를 지정하는 데 사용됩니다.

정리:

OpenContainer 위젯을 사용함으로써, Flutter 앱에 매끄럽고 직관적인 화면 전환 효과를 추가할 수 있습니다. 이는 사용자 경험을 크게 향상시키며, 앱의 전반적인 매력을 높여줍니다. 위의 예제 코드는 OpenContainer의 기본적인 사용 방법을 보여주며, 이를 통해 다양한 애니메이션 효과와 상세 화면 전환을 쉽게 구현할 수 있음을 알 수 있습니다.

profile
공부하는 개발자

0개의 댓글