Skip to content

Commit

Permalink
👽️ Create Screen Detail and BarCart
Browse files Browse the repository at this point in the history
  • Loading branch information
ChunhThanhDe committed Dec 4, 2024
1 parent 30e5f6c commit 79b23b8
Show file tree
Hide file tree
Showing 2 changed files with 245 additions and 0 deletions.
165 changes: 165 additions & 0 deletions foods_selection_screen/lib/presentation/detail/detail_screen.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
import 'package:flutter/material.dart';
import 'package:foods_selection_screen/data/food_data.dart';
import 'package:foods_selection_screen/presentation/detail/widgets/cart_bar.dart';

class DetailScreen extends StatefulWidget {
final Item data;
final String tag;

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

@override
State<DetailScreen> createState() => _DetailScreenState();
}

class _DetailScreenState extends State<DetailScreen>
with SingleTickerProviderStateMixin {
bool showCart = false;
late final AnimationController _rotationController;

@override
void initState() {
super.initState();
_rotationController = AnimationController(
vsync: this,
duration: const Duration(seconds: 10),
)..repeat();
}

@override
void dispose() {
_rotationController.dispose();
super.dispose();
}

@override
Widget build(BuildContext context) {
return Scaffold(
body: Stack(
children: [
SafeArea(
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 20),
child: Column(
children: [
_buildHeader(context),
const SizedBox(height: 20),
_buildRotatingFoodImage(),
const Spacer(),
_buildFoodTitle(),
const SizedBox(height: 10),
_buildRating(),
const SizedBox(height: 10),
_buildDescription(),
const Spacer(),
_buildPriceAndCartButton(),
const Spacer(),
],
),
),
),
// _buildCartBar(context),
CartBar(
showCart: showCart,
onClose: () => setState(() => showCart = false),
),
],
),
);
}

Widget _buildHeader(BuildContext context) {
return Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
IconButton(
onPressed: () => Navigator.pop(context),
icon: const Icon(Icons.arrow_back_ios),
),
GestureDetector(
onTap: () => setState(() => showCart = true),
child: CircleAvatar(
radius: 20,
backgroundColor: Theme.of(context).scaffoldBackgroundColor,
child: const Icon(Icons.shopping_cart, color: Colors.black),
),
),
],
);
}

Widget _buildRotatingFoodImage() {
return Center(
child: RotationTransition(
turns: _rotationController,
child: Hero(
tag: widget.tag,
child: CircleAvatar(
radius: 150,
backgroundColor: Colors.transparent,
backgroundImage: AssetImage(widget.data.image),
),
),
),
);
}

Widget _buildFoodTitle() {
return Text(
widget.data.title,
style: const TextStyle(fontWeight: FontWeight.bold, fontSize: 32),
textAlign: TextAlign.center,
);
}

Widget _buildRating() {
return Row(
mainAxisAlignment: MainAxisAlignment.center,
children: List.generate(
5,
(index) => const Icon(Icons.star, color: Colors.orange, size: 20),
),
);
}

Widget _buildDescription() {
return Text(
widget.data.description,
style: TextStyle(fontSize: 16, color: Colors.grey.shade600),
maxLines: 4,
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.center,
);
}

Widget _buildPriceAndCartButton() {
return Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
"Giá món: ${widget.data.price} đ",
style: const TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
),
ElevatedButton(
onPressed: () {
setState(() => showCart = true);
},
style: ElevatedButton.styleFrom(
backgroundColor: Colors.black,
padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 10),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10),
),
),
child: const Text(
"Thêm món",
style: TextStyle(
fontSize: 18,
color: Colors.white,
),
),
),
],
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
import 'package:flutter/material.dart';
import 'package:foods_selection_screen/data/food_data.dart';

class CartBar extends StatelessWidget {
final bool showCart;
final Function() onClose;

const CartBar({
super.key,
required this.showCart,
required this.onClose,
});

@override
Widget build(BuildContext context) {
return AnimatedPositioned(
duration: const Duration(milliseconds: 300),
curve: Curves.easeInOutBack,
right: showCart ? 10 : -150,
top: MediaQuery.sizeOf(context).height * 0.2,
bottom: MediaQuery.sizeOf(context).height * 0.2,
child: Container(
width: 100,
height: MediaQuery.sizeOf(context).height * 0.6,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(20),
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.1),
blurRadius: 10,
),
],
),
child: SafeArea(
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 10),
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: [
GestureDetector(
onTap: onClose,
child: CircleAvatar(
radius: 22,
backgroundColor: Theme.of(context).scaffoldBackgroundColor,
child: const Icon(Icons.close, color: Colors.black),
),
),
const SizedBox(height: 20),
const Text("Đơn mua",
textAlign: TextAlign.center,
style: TextStyle(fontSize: 18)),
const SizedBox(height: 20),
Expanded(
child: ListView.builder(
itemCount: items.length,
itemBuilder: (context, index) =>
Image.asset(items[index].image, height: 50),
),
),
const SizedBox(height: 20),
const Text("Tổng:",
style:
TextStyle(fontSize: 18, fontWeight: FontWeight.bold)),
Text("${items.length} món",
style: const TextStyle(fontSize: 14)),
const SizedBox(height: 5),
const Text("250.000 đ",
style:
TextStyle(fontSize: 16, fontWeight: FontWeight.w800)),
const SizedBox(height: 20),
],
),
),
),
),
);
}
}

0 comments on commit 79b23b8

Please sign in to comment.