1. Card 이미지를 터치하면 Detail Screen으로 이동하는 방법을 배워보자.
(Detail Screen은 애니메이션을 통해 화면이 이동하는 것 처럼 보이지만 사실 그냥 렌더링 하는 것이다.)
지금까지 파일 트리
-home_screen.dart
makeList 함수 부분에서 코드가 너무 길어져서 Webtoon 위젯으로 만들어 주었다.
ListView makeList(AsyncSnapshot<List<WebtoonModel>> snapshot) {
return ListView.separated(
scrollDirection: Axis.horizontal,
itemCount: snapshot.data!.length,
padding: const EdgeInsets.symmetric(vertical: 10, horizontal: 20),
itemBuilder: (context, index) {
var webtoon = snapshot.data![index];
return Webtoon(
title: webtoon.title,
thumb: webtoon.thumb,
id: webtoon.id,
);
},
separatorBuilder: (context, index) => const SizedBox(
width: 20,
),
);
}
-webtoon_widget.dart
여기서 GestureDetector를 통해 화면의 이벤트를 감지 할 수 있고, 이때 터치하면 네비게이터를 통해 다른 화면으로 이동 할 수 있다. (실제로는 화면 이동이 아니라, statelessWidget을 렌더링 해주는 것임)
여기서 포인트는, 아래 MaterialPageRoute를 이용하면, ios 기기와 android 기기에 애니메이션이 약간 다르다. (RN과 같이)
똑같이 맞추려면 매뉴얼하게 작업을 해야 하는데 이때는 아래 내용을 참조 하자.
https://docs.flutter.dev/cookbook/animation/page-route-animation
만약 android에서 좌우로 이동하게 하려면 MaterialPageRoute부분 대신에 아래 코드 사용.
PageRouteBuilder(
transitionsBuilder:
(context, animation, secondaryAnimation, child) {
var begin = const Offset(1.0, 0.0);
var end = Offset.zero;
var curve = Curves.ease;
var tween =
Tween(begin: begin, end: end).chain(CurveTween(curve: curve));
return SlideTransition(
position: animation.drive(tween),
child: child,
);
},
pageBuilder: (context, anmation, secondaryAnimation) =>
DetailScreen(id: id, title: title, thumb: thumb),
),
import 'package:flutter/material.dart';
import 'package:toonflix/screens/detail_screen.dart';
class Webtoon extends StatelessWidget {
final String title, thumb, id;
const Webtoon({
super.key,
required this.title,
required this.thumb,
required this.id,
});
@override
Widget build(BuildContext context) {
return GestureDetector(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => DetailScreen(
title: title,
thumb: thumb,
id: id,
),
fullscreenDialog: true, //화면이 아래서 위로 올라오게 함
),
);
},
child: Column(
children: [
Container(
width: 250,
clipBehavior: Clip.hardEdge,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(15),
boxShadow: [
BoxShadow(
blurRadius: 15,
offset: const Offset(10, 10),
color: Colors.black.withOpacity(0.3),
)
]),
child: Image.network(
thumb,
),
),
Text(
title,
style: const TextStyle(fontSize: 18, fontWeight: FontWeight.w600),
),
],
),
);
}
}
- detail_screen.dart
터치하면 보이는 화면
import 'package:flutter/material.dart';
class DetailScreen extends StatelessWidget {
final String title, thumb, id;
const DetailScreen({
super.key,
required this.title,
required this.thumb,
required this.id,
});
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
appBar: AppBar(
elevation: 0,
centerTitle: true,
backgroundColor: Colors.white,
foregroundColor: Colors.green,
title: Text(
title,
style: const TextStyle(
fontSize: 24,
),
),
),
body: Column(
children: [
const SizedBox(
height: 50,
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
width: 250,
clipBehavior: Clip.hardEdge,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(15),
boxShadow: [
BoxShadow(
blurRadius: 15,
offset: const Offset(10, 10),
color: Colors.black.withOpacity(0.3),
)
]),
child: Image.network(
thumb,
),
),
],
),
],
),
);
}
}