Skip to content

Commit 913e2a9

Browse files
committed
Create clipping backdrop poster in detail screen
1 parent 8e99b7e commit 913e2a9

File tree

2 files changed

+150
-34
lines changed

2 files changed

+150
-34
lines changed

lib/src/ui/detail/detail_screen.dart

+106
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
import 'dart:io';
2+
3+
import 'package:flutter/cupertino.dart';
4+
import 'package:flutter/material.dart';
5+
import 'package:flutter_ui_cinemax/src/model/banner/banner_movie.dart';
6+
7+
class DetailScreen extends StatelessWidget {
8+
final BannerMovie bannerMovie;
9+
10+
DetailScreen(this.bannerMovie);
11+
12+
@override
13+
Widget build(BuildContext context) {
14+
var mediaQuery = MediaQuery.of(context);
15+
return Scaffold(
16+
body: Padding(
17+
padding: EdgeInsets.only(
18+
bottom:
19+
mediaQuery.padding.bottom == 0 ? 16.0 : mediaQuery.padding.bottom,
20+
),
21+
child: Column(
22+
children: <Widget>[
23+
Stack(
24+
children: <Widget>[
25+
WavyHeaderImage(bannerMovie.backdropPath),
26+
_buildWidgetAppBar(mediaQuery),
27+
],
28+
),
29+
],
30+
),
31+
),
32+
);
33+
}
34+
35+
Widget _buildWidgetAppBar(MediaQueryData mediaQuery) {
36+
return Padding(
37+
padding: EdgeInsets.only(
38+
left: 16.0,
39+
top: mediaQuery.padding.top == 0 ? 16.0 : mediaQuery.padding.top,
40+
right: 16.0,
41+
),
42+
child: Row(
43+
crossAxisAlignment: CrossAxisAlignment.center,
44+
children: <Widget>[
45+
Icon(
46+
Platform.isIOS ? Icons.arrow_back_ios : Icons.arrow_back,
47+
color: Colors.white,
48+
),
49+
Expanded(
50+
child: Image.asset(
51+
'assets/images/img_netflix_logo.png',
52+
height: 20.0,
53+
),
54+
),
55+
Icon(
56+
Icons.favorite_border,
57+
color: Colors.white,
58+
),
59+
],
60+
),
61+
);
62+
}
63+
}
64+
65+
class WavyHeaderImage extends StatelessWidget {
66+
final String backdropPath;
67+
68+
WavyHeaderImage(this.backdropPath);
69+
70+
@override
71+
Widget build(BuildContext context) {
72+
var mediaQuery = MediaQuery.of(context);
73+
return ClipPath(
74+
child: Image.asset(
75+
backdropPath,
76+
height: mediaQuery.size.height / 2,
77+
width: double.infinity,
78+
fit: BoxFit.cover,
79+
),
80+
clipper: BottomWaveClipper(),
81+
);
82+
}
83+
}
84+
85+
class BottomWaveClipper extends CustomClipper<Path> {
86+
@override
87+
Path getClip(Size size) {
88+
var path = Path();
89+
path.lineTo(0.0, size.height - 70.0);
90+
91+
var firstControlPoint = Offset(size.width / 2, size.height);
92+
var firstEndPoint = Offset(size.width, size.height - 70.0);
93+
path.quadraticBezierTo(firstControlPoint.dx, firstControlPoint.dy,
94+
firstEndPoint.dx, firstEndPoint.dy);
95+
96+
path.lineTo(size.width, size.height - 70.0);
97+
path.lineTo(size.width, 0.0);
98+
path.close();
99+
return path;
100+
}
101+
102+
@override
103+
bool shouldReclip(CustomClipper<Path> oldClipper) {
104+
return false;
105+
}
106+
}

lib/src/ui/home/home_screen.dart

+44-34
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
22
import 'package:flutter_ui_cinemax/res/color_app.dart';
33
import 'package:flutter_ui_cinemax/src/model/banner/banner_movie.dart';
44
import 'package:flutter_ui_cinemax/src/model/category/category.dart';
5+
import 'package:flutter_ui_cinemax/src/ui/detail/detail_screen.dart';
56

67
class HomeScreen extends StatelessWidget {
78
@override
@@ -98,45 +99,54 @@ class HomeScreen extends StatelessWidget {
9899
var bannerMovie = listBanner[index % 7];
99100
return Padding(
100101
padding: const EdgeInsets.symmetric(horizontal: 8.0),
101-
child: Container(
102-
decoration: BoxDecoration(
103-
borderRadius: BorderRadius.circular(16.0),
104-
image: DecorationImage(
105-
image: AssetImage(bannerMovie.backdropPath),
106-
fit: BoxFit.cover,
102+
child: GestureDetector(
103+
onTap: () {
104+
Navigator.of(context).push(
105+
MaterialPageRoute(builder: (BuildContext context) {
106+
return DetailScreen(bannerMovie);
107+
}),
108+
);
109+
},
110+
child: Container(
111+
decoration: BoxDecoration(
112+
borderRadius: BorderRadius.circular(16.0),
113+
image: DecorationImage(
114+
image: AssetImage(bannerMovie.backdropPath),
115+
fit: BoxFit.cover,
116+
),
107117
),
108-
),
109-
child: Stack(
110-
children: <Widget>[
111-
Opacity(
112-
opacity: 0.3,
113-
child: Container(
114-
decoration: BoxDecoration(
115-
borderRadius: BorderRadius.circular(16.0),
116-
color: Colors.black,
118+
child: Stack(
119+
children: <Widget>[
120+
Opacity(
121+
opacity: 0.3,
122+
child: Container(
123+
decoration: BoxDecoration(
124+
borderRadius: BorderRadius.circular(16.0),
125+
color: Colors.black,
126+
),
117127
),
118128
),
119-
),
120-
Padding(
121-
padding: const EdgeInsets.only(
122-
left: 16.0,
123-
right: 16.0,
124-
bottom: 16.0,
125-
),
126-
child: Align(
127-
alignment: Alignment.bottomLeft,
128-
child: Text(
129-
bannerMovie.title,
130-
style: Theme.of(context).textTheme.title.merge(
131-
TextStyle(
132-
color: Colors.white,
129+
Padding(
130+
padding: const EdgeInsets.only(
131+
left: 16.0,
132+
right: 16.0,
133+
bottom: 16.0,
134+
),
135+
child: Align(
136+
alignment: Alignment.bottomLeft,
137+
child: Text(
138+
bannerMovie.title,
139+
style: Theme.of(context).textTheme.title.merge(
140+
TextStyle(
141+
color: Colors.white,
142+
),
133143
),
134-
),
135-
maxLines: 2,
144+
maxLines: 2,
145+
),
136146
),
137-
),
138-
)
139-
],
147+
)
148+
],
149+
),
140150
),
141151
),
142152
);

0 commit comments

Comments
 (0)