Online Shop App – Flutter UI – Speed Code. Copy and paste the below code as per your requirements.
main.dart
import 'package:flutter/material.dart';
import 'package:shop_app/constants.dart';
import 'package:shop_app/screens/home/home_screen.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Flutter Demo',
theme: ThemeData(
textTheme: Theme.of(context).textTheme.apply(bodyColor: kTextColor),
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: HomeScreen(),
);
}
}
constants.dart
import 'package:flutter/material.dart';
const kTextColor = Color(0xFF535353);
const kTextLightColor = Color(0xFFACACAC);
const kDefaultPadding = 20.0;
models/product.dart
import 'package:flutter/material.dart';
class Product{
final String image, title, description;
final int price,size, id;
final Color color;
Product({
required this.id,
required this.image,
required this.title,
required this.price,
required this.description,
required this.size,
required this.color
});
}
List<Product> products = [
Product(
id: 1,
image: "assets/images/bag_1.png",
title: "Office Code",
price: 234,
description: "Example Text Example Text Example Text Example Text Example Text Example Text Example Text Example Text",
size: 12,
color: Color(0xFF3D82AE)),
Product(
id: 2,
image: "assets/images/bag_2.png",
title: "Belt Bag",
price: 234,
description: "Example Text",
size: 8,
color: Color(0xFFD3A984)),
Product(
id: 3,
image: "assets/images/bag_3.png",
title: "Hang Top",
price: 234,
description: "Example Text",
size: 10,
color: Color(0xFF989493)),
Product(
id: 4,
image: "assets/images/bag_4.png",
title: "Old Fashion",
price: 234,
description: "Example Text",
size: 11,
color: Color(0xFFE6B398)),
Product(
id: 5,
image: "assets/images/bag_5.png",
title: "Office Code",
price: 234,
description: "Example Text",
size: 12,
color: Color(0xFFFB7883)),
Product(
id: 6,
image: "assets/images/bag_6.png",
title: "Office Code",
price: 234,
description: "Example Text",
size: 12,
color: Color(0xFFAEAEAE)),
];
screens/details/components/body.dart
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:shop_app/constants.dart';
import '../../../models/product.dart';
class Body extends StatelessWidget{
final Product? product;
const Body({Key?key,this.product}):super(key: key);
@override
Widget build(BuildContext context)
{
Size size = MediaQuery.of(context).size;
return SingleChildScrollView(
child: Column(
children: <Widget>[
SizedBox(height: size.height,
child: Stack(
children: <Widget>[
Container(
margin: EdgeInsets.only(top: size.height*0.3),
padding: EdgeInsets.only(top: size.height*0.12,left: kDefaultPadding,right: kDefaultPadding),
decoration: BoxDecoration(color: Colors.white,borderRadius: BorderRadius.only(
topLeft: Radius.circular(24),
topRight: Radius.circular(24),
bottomLeft: Radius.circular(24),
bottomRight: Radius.circular(24),
)),
child: Column(children: <Widget>[
Row(
children: <Widget>[
Expanded(child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text("Color"),
Row(
children: <Widget>[
ColorDot(color: Color(0XFF345C95),isSelected: true,),
ColorDot(color: Color(0XFFF8C078),),
ColorDot(color: Color(0XFFA29B9B),)
],
)
],
),),
Expanded(child: RichText(text: TextSpan(
children: [
TextSpan(
style: TextStyle(color: kTextColor),
text: "Size\n"
),
TextSpan(
style: Theme.of(context).textTheme.headline5!.copyWith(fontWeight: FontWeight.bold),
text: "${product!.size} cm"
)
]
)))
],
),
Padding(padding: const EdgeInsets.symmetric(vertical: kDefaultPadding),
child: Text(product!.description,style: TextStyle(height: 1.5),),
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
CartCounter(),
Container(
height: 32,
width: 32,
decoration: BoxDecoration(
color: Color(0xFFFF6464),
shape: BoxShape.circle,
),
child: SvgPicture.asset("assets/icons/heart.svg",fit: BoxFit.none,),
)
],
),
Padding(padding: const EdgeInsets.symmetric(vertical: kDefaultPadding),
child: Row(
children: [Container(
margin: EdgeInsets.only(right: kDefaultPadding),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(18),
border: Border.all(color: product!.color)),
child: IconButton(icon: SvgPicture.asset("assets/icons/add_to_cart.svg"),onPressed: (){},),
),
Expanded(child: SizedBox(height: 50,
child: ElevatedButton(
style: ElevatedButton.styleFrom(primary: product!.color,shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(18))),
onPressed: (){},
child: Text(
"Buy Now".toUpperCase(),
style: TextStyle(fontSize: 17,fontWeight: FontWeight.bold,color: Colors.white),
),
),))
],
),
)
],),
),
Padding(padding: const EdgeInsets.symmetric(horizontal: kDefaultPadding),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
"Marvel Handbag",style: TextStyle(color: Colors.white),
),
Text(product!.title,style: Theme.of(context).textTheme.headline4!.copyWith(color: Colors.white,fontWeight: FontWeight.bold),),
SizedBox(height: kDefaultPadding,),
Row(children: <Widget>[
RichText(text: TextSpan(
children: [
TextSpan(text: "Price\n"),
TextSpan(text: "\$${product!.price}",style: Theme.of(context).textTheme.headline4!.copyWith(color: Colors.white,fontWeight: FontWeight.bold))
]
)),
SizedBox(width: kDefaultPadding,),
Expanded(child: Image.asset(product!.image,fit: BoxFit.fill,),)
],)
],
),
)
],
),
)
],
),
);
}
}
class ColorDot extends StatelessWidget{
final Color? color;
final bool isSelected;
const ColorDot({Key?key,this.color,this.isSelected=false}): super(key: key);
@override
Widget build (BuildContext context)
{
return Container(
margin: EdgeInsets.only(top: kDefaultPadding/4,right: kDefaultPadding/2),
padding: EdgeInsets.all(2.5),
height: 24,
width: 24,
decoration: BoxDecoration(
shape: BoxShape.circle,
border: Border.all(color: isSelected ? color! : Colors.transparent)),
child: DecoratedBox(
decoration: BoxDecoration(
color: color!,
shape: BoxShape.circle
),
),
);
}
}
class CartCounter extends StatefulWidget{
@override
_CartCounterState createState()=> _CartCounterState();
}
class _CartCounterState extends State<CartCounter>{
int noOfItems = 1;
@override
Widget build(BuildContext context)
{
return Row(
children: [
buildOutlineButton(icon: Icons.remove,press: (){
setState(() {
noOfItems--;
});
}),
Padding(padding:const EdgeInsets.symmetric(horizontal: kDefaultPadding/2),
child: Text(noOfItems.toString().padLeft(2,"0"),style: Theme.of(context).textTheme.headline6,),
),
buildOutlineButton(icon: Icons.add,press: (){
setState(() {
noOfItems++;
});
}),
],
);
}
SizedBox buildOutlineButton({IconData? icon,VoidCallback? press})
{
return SizedBox(
width: 40,
height: 32,
child: OutlinedButton(
style: ButtonStyle(
padding: MaterialStateProperty.all(
EdgeInsets.zero,
),
shape: MaterialStateProperty.all<RoundedRectangleBorder>(
RoundedRectangleBorder(
borderRadius: BorderRadius.circular(13.0)
)
)
),
onPressed: press,
child: Icon(icon),
),
);
}
}
screens/details/details_screen.dart
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:shop_app/constants.dart';
import 'package:shop_app/screens/details/components/body.dart';
import '../../models/product.dart';
class DetailsScreen extends StatelessWidget{
final Product?product;
const DetailsScreen({Key? key,this.product}): super(key: key);
@override
Widget build(BuildContext context)
{
return Scaffold(
backgroundColor: product!.color,
appBar: AppBar(
backgroundColor: product!.color,
elevation: 0,
leading: IconButton(
onPressed:()=>Navigator.pop(context),
icon: SvgPicture.asset("assets/icons/back.svg",color:Colors.white),
),
actions: [
IconButton(
onPressed:()=>Navigator.pop(context),
icon: SvgPicture.asset("assets/icons/search.svg",color:Colors.white),
),
IconButton(
onPressed:()=>Navigator.pop(context),
icon: SvgPicture.asset("assets/icons/cart.svg",color:Colors.white),
),
SizedBox(width: kDefaultPadding/2,)
],
),
body: Body(product: product,),
);
}
}
screens/home/components/body.dart
import 'package:flutter/material.dart';
import 'package:shop_app/constants.dart';
import 'package:shop_app/models/product.dart';
import 'package:shop_app/screens/details/details_screen.dart';
class Body extends StatelessWidget{
@override
Widget build(BuildContext context)
{
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Padding(padding: const EdgeInsets.symmetric(horizontal: kDefaultPadding),
child: Text("Women",
style: Theme.of(context)
.textTheme
.headline5
!.copyWith(fontWeight: FontWeight.bold),),),
Categories(),
Expanded(child:
Padding(
padding: const EdgeInsets.symmetric(horizontal: kDefaultPadding),
child: GridView.builder(
itemCount: products.length,
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount:2,mainAxisSpacing:kDefaultPadding,crossAxisSpacing:kDefaultPadding,childAspectRatio: 0.75),
itemBuilder: (context,index)=>ItemCard(product: products[index],press: ()=>Navigator.push(context, MaterialPageRoute(builder: (context)=> DetailsScreen(product: products[index],))),)),
)
)
],
);
}
}
class ItemCard extends StatelessWidget{
final Product? product;
final VoidCallback? press;
const ItemCard({ Key?key,this.product,this.press}): super(key: key);
@override
Widget build(BuildContext context)
{
return GestureDetector(
onTap: press,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Expanded(child: Container(
padding: EdgeInsets.all(kDefaultPadding),
decoration: BoxDecoration(color: products[0].color,
borderRadius: BorderRadius.circular(16)
),
child: Image.asset(product!.image),
),),
Padding(padding: const EdgeInsets.symmetric(vertical: kDefaultPadding/4),
child: Text(product!.title,style: TextStyle(color: kTextLightColor),
),),
Text("\$"+product!.price.toString(),style: TextStyle(fontWeight: FontWeight.bold),)
],
)
);
}
}
class Categories extends StatefulWidget{
@override
_CategoriesState createState() => _CategoriesState();
}
class _CategoriesState extends State<Categories>{
List<String> categories =["Hand Bag","Jewellery","Footwear","Dresses"];
int selectedIndex = 0;
@override
Widget build(BuildContext context)
{
return Padding(
padding: const EdgeInsets.symmetric(vertical: kDefaultPadding),
child: SizedBox(
height: 25,
child: ListView.builder(
scrollDirection: Axis.horizontal,
itemCount: categories.length,
itemBuilder: (context,index)=>
buildCategory(index),
),
),);
}
Widget buildCategory(int index){
return GestureDetector(
onTap: (){
selectedIndex = index;
},
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: kDefaultPadding),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [Text(categories[index],
style: TextStyle(
fontWeight: FontWeight.bold,
color: selectedIndex == index ?kTextColor : kTextLightColor),),
Container(
margin: EdgeInsets.only(top: kDefaultPadding/4),
height: 2,
width: 30,
color: selectedIndex == index ? Colors.black : Colors.transparent,
)
],
),
),
);
}
}
screens/home/home_screen.dart
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:shop_app/constants.dart';
import 'package:shop_app/screens/home/components/body.dart';
class HomeScreen extends StatelessWidget{
@override
Widget build(BuildContext context){
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.white,
elevation: 0,
leading: IconButton(
icon: SvgPicture.asset("assets/icons/back.svg"),
onPressed: (){},
),
actions: <Widget>[
IconButton(onPressed: (){}, icon: SvgPicture.asset("assets/icons/search.svg",color: kTextColor,)),
IconButton(onPressed: (){}, icon: SvgPicture.asset("assets/icons/cart.svg",color: kTextColor,)),
SizedBox(width: kDefaultPadding/2,)
],
),
body: Body(),
);
}
}