
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의 주요 속성:openBuilder에 정의된 위젯으로 전환됩니다.위 코드에서는 ContainerTransformScreen이라는 StatefulWidget을 사용하여, 사용자가 그리드 뷰와 리스트 뷰 사이를 전환할 수 있도록 합니다. 이를 통해 OpenContainer 위젯의 사용법을 다양한 상황에서 보여줍니다.
각 항목은 OpenContainer 위젯을 사용하여 구현됩니다. closedBuilder는 메인 화면에서 사용자에게 보여지는 부분(이미지와 텍스트)을 정의하고, openBuilder는 사용자가 해당 항목을 탭했을 때 보여질 상세 화면을 정의합니다.
DetailScreen):DetailScreen은 사용자가 항목을 탭했을 때 나타나는 화면입니다. 이 화면에는 대형 이미지와 "Detail Screen"이라는 텍스트가 표시됩니다. 이 클래스는 image 매개변수를 필요로 하는데, 이는 각 항목에 대한 이미지를 지정하는 데 사용됩니다.
OpenContainer 위젯을 사용함으로써, Flutter 앱에 매끄럽고 직관적인 화면 전환 효과를 추가할 수 있습니다. 이는 사용자 경험을 크게 향상시키며, 앱의 전반적인 매력을 높여줍니다. 위의 예제 코드는 OpenContainer의 기본적인 사용 방법을 보여주며, 이를 통해 다양한 애니메이션 효과와 상세 화면 전환을 쉽게 구현할 수 있음을 알 수 있습니다.