Skip to content

Commit 331d51d

Browse files
committed
Update DetailsPage layout and improve UI responsiveness
1 parent ead1ad9 commit 331d51d

File tree

1 file changed

+136
-138
lines changed

1 file changed

+136
-138
lines changed

lib/app/view/details_page.dart

Lines changed: 136 additions & 138 deletions
Original file line numberDiff line numberDiff line change
@@ -67,168 +67,166 @@ class _DetailsPageState extends State<DetailsPage> {
6767
state is MovieDetailsLoaded ? state.movieDetails : null;
6868
final credits = state is MovieDetailsLoaded ? state.credits : null;
6969

70-
return SafeArea(
71-
child: SingleChildScrollView(
72-
child: Column(
73-
crossAxisAlignment: CrossAxisAlignment.start,
74-
children: [
75-
Stack(
76-
children: [
77-
Container(
78-
height: 320,
79-
width: double.infinity,
80-
decoration: BoxDecoration(
81-
borderRadius: const BorderRadius.only(
82-
bottomLeft: Radius.circular(32),
83-
bottomRight: Radius.circular(32),
84-
),
85-
image: DecorationImage(
86-
image: NetworkImage(
87-
'https://image.tmdb.org/t/p/w500${widget.movie.backdropPath ?? widget.movie.posterPath}',
88-
),
89-
fit: BoxFit.cover,
70+
return SingleChildScrollView(
71+
child: Column(
72+
crossAxisAlignment: CrossAxisAlignment.start,
73+
children: [
74+
Stack(
75+
children: [
76+
Container(
77+
height: 320,
78+
width: double.infinity,
79+
decoration: BoxDecoration(
80+
borderRadius: const BorderRadius.only(
81+
bottomLeft: Radius.circular(32),
82+
bottomRight: Radius.circular(32),
83+
),
84+
image: DecorationImage(
85+
image: NetworkImage(
86+
'https://image.tmdb.org/t/p/w500${widget.movie.backdropPath ?? widget.movie.posterPath}',
9087
),
88+
fit: BoxFit.cover,
9189
),
9290
),
93-
Positioned(
94-
top: 16,
95-
left: 16,
96-
child: _CircleButton(
97-
icon: Icons.arrow_back,
98-
onTap: () => Navigator.of(context).pop(),
99-
),
91+
),
92+
Positioned(
93+
top: 16 + MediaQuery.of(context).viewPadding.top,
94+
left: 16,
95+
child: _CircleButton(
96+
icon: Icons.arrow_back,
97+
onTap: () => Navigator.of(context).pop(),
10098
),
101-
Positioned(
102-
top: 16,
103-
right: 16,
104-
child: _CircleButton(
105-
icon: _isFavorite
106-
? Icons.favorite
107-
: Icons.favorite_border,
108-
onTap: () async {
109-
await context
110-
.read<FavoriteMoviesCubit>()
111-
.toggleFavorite(widget.movie);
112-
await _checkFavoriteStatus();
113-
},
114-
),
99+
),
100+
Positioned(
101+
top: 16 + MediaQuery.of(context).viewPadding.top,
102+
right: 16,
103+
child: _CircleButton(
104+
icon: _isFavorite
105+
? Icons.favorite
106+
: Icons.favorite_border,
107+
onTap: () async {
108+
await context
109+
.read<FavoriteMoviesCubit>()
110+
.toggleFavorite(widget.movie);
111+
await _checkFavoriteStatus();
112+
},
115113
),
116-
Positioned(
117-
left: 24,
118-
bottom: 0,
119-
child: _RatingIndicator(
120-
percent: widget.movie.voteAverage / 10,
121-
),
114+
),
115+
Positioned(
116+
left: 24,
117+
bottom: 32,
118+
child: _RatingIndicator(
119+
percent: widget.movie.voteAverage / 10,
122120
),
123-
Positioned(
124-
left: 100,
125-
bottom: 32,
126-
right: 16,
127-
child: Column(
128-
crossAxisAlignment: CrossAxisAlignment.start,
129-
children: [
121+
),
122+
Positioned(
123+
left: 100,
124+
bottom: 32,
125+
right: 16,
126+
child: Column(
127+
crossAxisAlignment: CrossAxisAlignment.start,
128+
children: [
129+
Text(
130+
widget.movie.title,
131+
style: const TextStyle(
132+
color: Colors.white,
133+
fontSize: 24,
134+
fontWeight: FontWeight.bold,
135+
),
136+
),
137+
if (movieDetails != null) ...[
138+
const SizedBox(height: 4),
130139
Text(
131-
widget.movie.title,
140+
movieDetails.genres
141+
.map((g) => g.name)
142+
.join(', '),
132143
style: const TextStyle(
133-
color: Colors.black,
134-
fontSize: 24,
135-
fontWeight: FontWeight.bold,
144+
color: Colors.white,
145+
fontSize: 16,
136146
),
137147
),
138-
if (movieDetails != null) ...[
139-
const SizedBox(height: 4),
140-
Text(
141-
movieDetails.genres
142-
.map((g) => g.name)
143-
.join(', '),
144-
style: const TextStyle(
145-
color: Colors.black54,
146-
fontSize: 16,
147-
),
148-
),
149-
],
150148
],
151-
),
149+
],
152150
),
153-
],
151+
),
152+
],
153+
),
154+
const SizedBox(height: 24),
155+
Padding(
156+
padding: const EdgeInsets.symmetric(horizontal: 16),
157+
child: Text(
158+
widget.movie.overview,
159+
style: const TextStyle(
160+
color: Colors.black87,
161+
fontSize: 16,
162+
),
154163
),
164+
),
165+
if (movieDetails != null) ...[
155166
const SizedBox(height: 24),
156167
Padding(
157168
padding: const EdgeInsets.symmetric(horizontal: 16),
158-
child: Text(
159-
widget.movie.overview,
160-
style: const TextStyle(
161-
color: Colors.black87,
162-
fontSize: 16,
163-
),
164-
),
165-
),
166-
if (movieDetails != null) ...[
167-
const SizedBox(height: 24),
168-
Padding(
169-
padding: const EdgeInsets.symmetric(horizontal: 16),
170-
child: Row(
171-
children: [
172-
const Icon(Icons.access_time, color: Colors.black54),
173-
const SizedBox(width: 8),
174-
Text(
175-
'${movieDetails.runtime} min',
176-
style: const TextStyle(
177-
color: Colors.black54,
178-
fontSize: 16,
179-
),
180-
),
181-
const SizedBox(width: 24),
182-
const Icon(
183-
Icons.calendar_today,
169+
child: Row(
170+
children: [
171+
const Icon(Icons.access_time, color: Colors.black54),
172+
const SizedBox(width: 8),
173+
Text(
174+
'${movieDetails.runtime} min',
175+
style: const TextStyle(
184176
color: Colors.black54,
177+
fontSize: 16,
185178
),
186-
const SizedBox(width: 8),
187-
Text(
188-
movieDetails.releaseDate ?? 'N/A',
189-
style: const TextStyle(
190-
color: Colors.black54,
191-
fontSize: 16,
192-
),
179+
),
180+
const SizedBox(width: 24),
181+
const Icon(
182+
Icons.calendar_today,
183+
color: Colors.black54,
184+
),
185+
const SizedBox(width: 8),
186+
Text(
187+
movieDetails.releaseDate ?? 'N/A',
188+
style: const TextStyle(
189+
color: Colors.black54,
190+
fontSize: 16,
193191
),
194-
],
195-
),
196-
),
197-
],
198-
if (credits != null) ...[
199-
const SizedBox(height: 24),
200-
const Padding(
201-
padding: EdgeInsets.symmetric(horizontal: 16),
202-
child: Text(
203-
'Cast',
204-
style: TextStyle(
205-
color: Colors.black,
206-
fontSize: 18,
207-
fontWeight: FontWeight.bold,
208192
),
209-
),
193+
],
210194
),
211-
const SizedBox(height: 12),
212-
SizedBox(
213-
height: 120,
214-
child: ListView.builder(
215-
scrollDirection: Axis.horizontal,
216-
padding: const EdgeInsets.symmetric(horizontal: 16),
217-
itemCount: credits.cast.length,
218-
itemBuilder: (context, index) {
219-
final cast = credits.cast[index];
220-
return _CastCard(
221-
name: cast.name,
222-
image: cast.profilePath != null
223-
? 'https://image.tmdb.org/t/p/w200${cast.profilePath}'
224-
: 'https://via.placeholder.com/200x300?text=No+Image',
225-
);
226-
},
195+
),
196+
],
197+
if (credits != null) ...[
198+
const SizedBox(height: 24),
199+
const Padding(
200+
padding: EdgeInsets.symmetric(horizontal: 16),
201+
child: Text(
202+
'Cast',
203+
style: TextStyle(
204+
color: Colors.black,
205+
fontSize: 18,
206+
fontWeight: FontWeight.bold,
227207
),
228208
),
229-
],
209+
),
210+
const SizedBox(height: 12),
211+
SizedBox(
212+
height: 120,
213+
child: ListView.builder(
214+
scrollDirection: Axis.horizontal,
215+
padding: const EdgeInsets.symmetric(horizontal: 16),
216+
itemCount: credits.cast.length,
217+
itemBuilder: (context, index) {
218+
final cast = credits.cast[index];
219+
return _CastCard(
220+
name: cast.name,
221+
image: cast.profilePath != null
222+
? 'https://image.tmdb.org/t/p/w200${cast.profilePath}'
223+
: 'https://via.placeholder.com/200x300?text=No+Image',
224+
);
225+
},
226+
),
227+
),
230228
],
231-
),
229+
],
232230
),
233231
);
234232
},

0 commit comments

Comments
 (0)