E-Commerce using Flutter

Sandeep Kumar Patel
13 min readAug 26, 2021

by -Sandeep Kumar Patel

What is Flutter?

Back in the days of Objective C/Swift and Java/Kotlin as primary languages for mobile development, building apps was expensive. You had to build two separate apps, which obviously meant doing the work twice.

To solve this problem, several frameworks have been constructed for the creation of hybrid (or cross-platform) apps in HTML5 and Javascript. Among the cross-platform toolkits, including Phonegap, Xamarin, React Native, and more, the Flutter framework has quickly become increasingly popular among developers, enterprises, entrepreneurs and users.

Flutter is a portable UI toolkit for building native-like apps across mobile, web and desktop, from a single codebase. It uses the programming language Dart and incorporates Material Design and Cupertino widgets. Flutter developers can create spectacular UI that looks and feels native. It behaves naturally on any platform, even though you’re using one codebase.

Flutter is the only framework with a mobile SDK that provides a responsive style without using a Javascript bridge, thereby reaching a level of performance that rivals its cousin and direct competitor React Native. It easily integrates with the different platforms such as Android, IOS and Linux, MAC, Windows and Google Fuchsia applications.

What is Flutter used for?

Flutter is one of the best solutions to develop apps for Android and iOS, without having to write in a different codebase for each platform. The smartphone versions of these apps function as true, native apps on Apple and Android devices and are compiled for the respective platform before publication. They do not need a runtime module or a browser. Using the same codebase, it is also possible to create web apps for browsers as well as native programs for Windows, Linux and macOS.

Google itself uses Flutter for several modules of the Google Assistant and for the user interface of the Google Home hub. Well known e-commerce service providers s

What programming language is Flutter based on?

The Flutter SDK is based on the Dart programming language, also developed by Google. It’s intent is to supplant classic JavaScript. On a server, Dart programs can be run directly, while in the browser they are converted to JavaScript using the Dart2js transcompiler.

Apps for Google’s new platform, Fuchsia, are developed directly with Dart. Its structure is similar to that of well-known object-oriented programming languages such as Java or C#.

‍It’s All Widgets: The Flutter principle

Flutter is a widget-based technology. This means that you can apply object-oriented programming to any element. One of the benefits of using Flutter is that you can modify or customize widgets with ease. In addition, it provides UI widgets that meet key web application design requirements.

Flutter, as an open-source framework, has attracted a broad and active community of developers since its release. This community constantly publishes usable code examples and supports developers in creating new, innovative, beautiful cross-platform apps.

‍Pros and cons of Flutter app development

Every programming language has its advantages and disadvantages. But, in most cases, we can say that the advantages of Flutter, compared to similar technologies, clearly outweigh its disadvantages.

‍Pros of Flutter app development

Flutter has numerous advantages over its competitors. These advantages are inherent in the programming language and in the set of development tools that allow Flutter to solve issues that other languages cannot cope with.

1. One codebase for all platforms

Gone are the days of having to write a code for Android and another codebase for iOS devices. Flutter’s code reusability allows you to write just one codebase and use it on not only for mobile Android and iOS but even for web, desktop and more. This cuts development time significantly, removes cost and enables you launch your app that much faster.

2. “It’s all Widgets” principle offers countless possibilities

Flutter’s custom widgets are an absolute delight when it comes to creating great visuals for your app. At the same time, you don’t have to worry about the UI on different devices.

3. Rich libraries

Flutter uses the Skia Graphics Library which is a fast and mature open-source graphics library. It redraws the UI every time a view changes. The result? A quick loading and smooth app experience.

4. Fast testing with hot reload

The hot reload feature make the app development much quicker. With Flutter there is no need to reload the app to see every single change you make in the code. You can easily make changes in your app in real time, so you have more opportunity to experiment with the code and fix bugs on the go.

‍Cons of Flutter app development

There are no flawless technology solutions, and Flutter is no exception. Flutter’s cons aren’t exactly deal-breakers, but here are a few reasons why it might not be the ideal toolkit for a specific app.

1. Large file size because of the widgets

Flutter apps are quite large and “heavy” to start with. They occupy a lot of space and take longer to download or update.

2. Complex updating

Updating programming requirements in operating systems requires updating Flutter modules. Since the modules are integrated as fixed elements in the program, the latter must also be recompiled and reinstalled on the devices.

3. Limited set of tools and libraries

Flutter is a quite new development framework, so in some cases you may not be able to get the desired functions in the current library. Flutter will take some time to create certain tools, expand functionality and develop the community.

Application Screen-

Fullter Code File-

<manifest xmlns:android=”http://schemas.android.com/apk/res/android"
package=”com.thealphamerc.flutter_ecommerce_app”>
<! — Flutter needs it to communicate with the running application
to allow setting breakpoints, to provide hot reload, etc.

<uses-permission android:name=”android.permission.INTERNET”/>
</manifest>
package com.thealphamerc.flutter_ecommerce_app

import io.flutter.embedding.android.FlutterActivity

class MainActivity: FlutterActivity() {
}
<manifest xmlns:android=”http://schemas.android.com/apk/res/android"
package=”com.thealphamerc.flutter_ecommerce_app”>
<application
android:label=”flutter_ecommerce_app”
android:icon=”@mipmap/ic_launcher”>
<activity
android:name=”.MainActivity”
android:launchMode=”singleTop”
android:theme=”@style/LaunchTheme
android:configChanges=”orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode”
android:hardwareAccelerated=”true”
android:windowSoftInputMode=”adjustResize”>
<! — Specifies an Android theme to apply to this Activity as soon as
the Android process has started. This theme is visible to the user
while the Flutter UI initializes. After that, this theme continues
to determine the Window background behind the Flutter UI. →
<meta-data
android:name=”io.flutter.embedding.android.NormalTheme”
android:resource=”@style/NormalTheme
/>
<! — Displays an Android View that continues showing the launch screen
Drawable until Flutter paints its first frame, then this splash
screen fades out. A splash screen is useful to avoid any visual
gap between the end of Android’s launch screen and the painting of
Flutter’s first frame. →
<meta-data
android:name=”io.flutter.embedding.android.SplashScreenDrawable”
android:resource=”@drawable/launch_background
/>
<intent-filter>
<action android:name=”android.intent.action.MAIN”/>
<category android:name=”android.intent.category.LAUNCHER”/>
</intent-filter>
</activity>
<! — Don’t delete the meta-data below.
This is used by the Flutter tool to generate GeneratedPluginRegistrant.java →
<meta-data
android:name=”flutterEmbedding”
android:value=”2" />
</application>
</manifest>
<?xml version=”1.0" encoding=”utf-8"?>
<! — Modify this file to customize your launch splash screen →
<layer-list xmlns:android=”http://schemas.android.com/apk/res/android”>
<item android:drawable=”?android:colorBackground” />

<! — You can insert your own image assets here →
<! — <item>
<bitmap
android:gravity=”center”
android:src=”@mipmap/launch_image” />
</item> →
<item>
<bitmap
android:gravity=”center”
android:src=”@drawable/ic_launcher” />
</item>
</layer-list>
<manifest xmlns:android=”http://schemas.android.com/apk/res/android
package=”com.thealphamerc.flutter_ecommerce_app">
<! — Flutter needs it to communicate with the running application
to allow setting breakpoints, to provide hot reload, etc.

<uses-permission android:name=”android.permission.INTERNET”/>
</manifest>
1.69 KB

def localProperties = new Properties()
def localPropertiesFile = rootProject.file(‘local.properties’)
if (localPropertiesFile.exists()) {
localPropertiesFile.withReader(‘UTF-8’) { reader ->
localProperties.load(reader)
}
}

def flutterRoot = localProperties.getProperty(‘flutter.sdk’)
if (flutterRoot == null) {
throw new GradleException(“Flutter SDK not found. Define location with flutter.sdk in the local.properties file.”)
}

def flutterVersionCode = localProperties.getProperty(‘flutter.versionCode’)
if (flutterVersionCode == null) {
flutterVersionCode = ‘1’
}

def flutterVersionName = localProperties.getProperty(‘flutter.versionName’)
if (flutterVersionName == null) {
flutterVersionName = ‘1.0’
}

apply plugin: ‘com.android.application’
apply plugin: ‘kotlin-android’
apply from: “$flutterRoot/packages/flutter_tools/gradle/flutter.gradle”

android {
compileSdkVersion 30

sourceSets {
main.java.srcDirs += ‘src/main/kotlin’
}

defaultConfig {
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
applicationId “com.thealphamerc.flutter_ecommerce_app”
minSdkVersion 16
targetSdkVersion 30
versionCode flutterVersionCode.toInteger()
versionName flutterVersionName
}

buildTypes {
release {
// TODO: Add your own signing config for the release build.
// Signing with the debug keys for now, so `flutter run — release` works.
signingConfig signingConfigs.debug
}
}
}

flutter {
source ‘../..’
}

dependencies {
implementation “org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version”
}
gradle-wrapper.jar
/.gradle
/captures/
/gradlew
/gradlew.bat
/local.properties
GeneratedPluginRegistrant.java

# Remember to never publicly share your keystore.
# See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app
key.properties
buildscript {
ext.kotlin_version = ‘1.3.50’
repositories {
google()
jcenter()
}

dependencies {
classpath ‘com.android.tools.build:gradle:4.1.0’
classpath “org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version”
}
}

allprojects {
repositories {
google()
jcenter()
}
}

rootProject.buildDir = ‘../build’
subprojects {
project.buildDir = “${rootProject.buildDir}/${project.name}”
}
subprojects {
project.evaluationDependsOn(‘:app’)
}

task clean(type: Delete) {
delete rootProject.buildDir
}
include ‘:app’

def localPropertiesFile = new File(rootProject.projectDir, “local.properties”)
def properties = new Properties()

assert localPropertiesFile.exists()
localPropertiesFile.withReader(“UTF-8”) { reader -> properties.load(reader) }

def flutterSdkPath = properties.getProperty(“flutter.sdk”)
assert flutterSdkPath != null, “flutter.sdk not set in local.properties”
apply from: “$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle”
def localProperties = new Properties()
def localPropertiesFile = rootProject.file(‘local.properties’)
if (localPropertiesFile.exists()) {
localPropertiesFile.withReader(‘UTF-8’) { reader ->
localProperties.load(reader)
}
}

def flutterRoot = localProperties.getProperty(‘flutter.sdk’)
if (flutterRoot == null) {
throw new GradleException(“Flutter SDK not found. Define location with flutter.sdk in the local.properties file.”)
}

def flutterVersionCode = localProperties.getProperty(‘flutter.versionCode’)
if (flutterVersionCode == null) {
flutterVersionCode = ‘1’
}

def flutterVersionName = localProperties.getProperty(‘flutter.versionName’)
if (flutterVersionName == null) {
flutterVersionName = ‘1.0’
}

apply plugin: ‘com.android.application’
apply plugin: ‘kotlin-android’
apply from: “$flutterRoot/packages/flutter_tools/gradle/flutter.gradle”

android {
compileSdkVersion 30

sourceSets {
main.java.srcDirs += ‘src/main/kotlin’
}

defaultConfig {
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
applicationId “com.thealphamerc.flutter_ecommerce_app”
minSdkVersion 16
targetSdkVersion 30
versionCode flutterVersionCode.toInteger()
versionName flutterVersionName
}

buildTypes {
release {
// TODO: Add your own signing config for the release build.
// Signing with the debug keys for now, so `flutter run — release` works.
signingConfig signingConfigs.debug
}
}
}

flutter {
source ‘../..’
}

dependencies {
implementation “org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version”
}
import ‘package:flutter/material.dart’;
import ‘package:flutter_ecommerce_app/src/config/route.dart’;
import ‘package:flutter_ecommerce_app/src/pages/mainPage.dart’;
import ‘package:flutter_ecommerce_app/src/pages/product_detail.dart’;
import ‘package:flutter_ecommerce_app/src/widgets/customRoute.dart’;
import ‘package:google_fonts/google_fonts.dart’;

import ‘src/themes/theme.dart’;

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: ‘E-Commerce ‘,
theme: AppTheme.lightTheme.copyWith(
textTheme: GoogleFonts.muliTextTheme(
Theme.of(context).textTheme,
),
),
debugShowCheckedModeBanner: false,
routes: Routes.getRoute(),
onGenerateRoute: (RouteSettings settings) {
if (settings.name.contains(‘detail’)) {
return CustomRoute<bool>(
builder: (BuildContext context) => ProductDetailPage());
} else {
return CustomRoute<bool>(
builder: (BuildContext context) => MainPage());
}
},
initialRoute: “MainPage”,
);
}
}
import ‘package:flutter/material.dart’;
import ‘package:flutter_ecommerce_app/src/pages/mainPage.dart’;

class Routes {
static Map<String, WidgetBuilder> getRoute() {
return <String, WidgetBuilder>{
‘/’: (_) => MainPage(),
// ‘/detail’: (_) => ProductDetailPage()
};
}
}

import ‘package:flutter/gestures.dart’;
import ‘package:flutter/material.dart’;
import ‘package:flutter_ecommerce_app/src/model/data.dart’;
import ‘package:flutter_ecommerce_app/src/themes/light_color.dart’;
import ‘package:flutter_ecommerce_app/src/themes/theme.dart’;
import ‘package:flutter_ecommerce_app/src/widgets/product_card.dart’;
import ‘package:flutter_ecommerce_app/src/widgets/product_icon.dart’;
import ‘package:flutter_ecommerce_app/src/widgets/extentions.dart’;

class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);

final String title;

@override
_MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
Widget _icon(IconData icon, {Color color = LightColor.iconColor}) {
return Container(
padding: EdgeInsets.all(10),
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(13)),
color: Theme.of(context).backgroundColor,
boxShadow: AppTheme.shadow),
child: Icon(
icon,
color: color,
),
).ripple(() {}, borderRadius: BorderRadius.all(Radius.circular(13)));
}

Widget _categoryWidget() {
return Container(
margin: EdgeInsets.symmetric(vertical: 10),
width: AppTheme.fullWidth(context),
height: 80,
child: ListView(
scrollDirection: Axis.horizontal,
children: AppData.categoryList
.map(
(category) => ProductIcon(
model: category,
onSelected: (model) {
setState(() {
AppData.categoryList.forEach((item) {
item.isSelected = false;
});
model.isSelected = true;
});
},
),
)
.toList(),
),
);
}

Widget _productWidget() {
return Container(
margin: EdgeInsets.symmetric(vertical: 10),
width: AppTheme.fullWidth(context),
height: AppTheme.fullWidth(context) * .7,
child: GridView(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 1,
childAspectRatio: 4 / 3,
mainAxisSpacing: 30,
crossAxisSpacing: 20),
padding: EdgeInsets.only(left: 20),
scrollDirection: Axis.horizontal,
children: AppData.productList
.map(
(product) => ProductCard(
product: product,
onSelected: (model) {
setState(() {
AppData.productList.forEach((item) {
item.isSelected = false;
});
model.isSelected = true;
});
},
),
)
.toList(),
),
);
}

Widget _search() {
return Container(
margin: AppTheme.padding,
child: Row(
children: <Widget>[
Expanded(
child: Container(
height: 40,
alignment: Alignment.center,
decoration: BoxDecoration(
color: LightColor.lightGrey.withAlpha(100),
borderRadius: BorderRadius.all(Radius.circular(10))),
child: TextField(
decoration: InputDecoration(
border: InputBorder.none,
hintText: “Search Products”,
hintStyle: TextStyle(fontSize: 12),
contentPadding:
EdgeInsets.only(left: 10, right: 10, bottom: 0, top: 5),
prefixIcon: Icon(Icons.search, color: Colors.black54)),
),
),
),
SizedBox(width: 20),
_icon(Icons.filter_list, color: Colors.black54)
],
),
);
}

@override
Widget build(BuildContext context) {
return Container(
height: MediaQuery.of(context).size.height — 210,
child: SingleChildScrollView(
physics: BouncingScrollPhysics(),
dragStartBehavior: DragStartBehavior.down,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
_search(),
_categoryWidget(),
_productWidget(),
],
),
),
);
}
}
import ‘package:flutter/material.dart’;
import ‘package:flutter_ecommerce_app/src/pages/home_page.dart’;
import ‘package:flutter_ecommerce_app/src/pages/shopping_cart_page.dart’;
import ‘package:flutter_ecommerce_app/src/themes/light_color.dart’;
import ‘package:flutter_ecommerce_app/src/themes/theme.dart’;
import ‘package:flutter_ecommerce_app/src/widgets/BottomNavigationBar/bottom_navigation_bar.dart’;
import ‘package:flutter_ecommerce_app/src/widgets/title_text.dart’;
import ‘package:flutter_ecommerce_app/src/widgets/extentions.dart’;

class MainPage extends StatefulWidget {
MainPage({Key key, this.title}) : super(key: key);

final String title;

@override
_MainPageState createState() => _MainPageState();
}

class _MainPageState extends State<MainPage> {
bool isHomePageSelected = true;
Widget _appBar() {
return Container(
padding: AppTheme.padding,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
RotatedBox(
quarterTurns: 4,
child: _icon(Icons.sort, color: Colors.black54),
),
ClipRRect(
borderRadius: BorderRadius.all(Radius.circular(13)),
child: Container(
decoration: BoxDecoration(
color: Theme.of(context).backgroundColor,
boxShadow: <BoxShadow>[
BoxShadow(
color: Color(0xfff8f8f8),
blurRadius: 10,
spreadRadius: 10),
],
),
child: Image.asset(“assets/user.png”),
),
).ripple(() {}, borderRadius: BorderRadius.all(Radius.circular(13)))
],
),
);
}

Widget _icon(IconData icon, {Color color = LightColor.iconColor}) {
return Container(
padding: EdgeInsets.all(10),
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(13)),
color: Theme.of(context).backgroundColor,
boxShadow: AppTheme.shadow),
child: Icon(
icon,
color: color,
),
).ripple(() {}, borderRadius: BorderRadius.all(Radius.circular(13)));
}

Widget _title() {
return Container(
margin: AppTheme.padding,
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
TitleText(
text: isHomePageSelected ? ‘Our’ : ‘Shopping’,
fontSize: 27,
fontWeight: FontWeight.w400,
),
TitleText(
text: isHomePageSelected ? ‘Products’ : ‘Cart’,
fontSize: 27,
fontWeight: FontWeight.w700,
),
],
),
Spacer(),
!isHomePageSelected
? Container(
padding: EdgeInsets.all(10),
child: Icon(
Icons.delete_outline,
color: LightColor.orange,
),
).ripple(() {}, borderRadius: BorderRadius.all(Radius.circular(13)))
: SizedBox()
],
));
}

void onBottomIconPressed(int index) {
if (index == 0 || index == 1) {
setState(() {
isHomePageSelected = true;
});
} else {
setState(() {
isHomePageSelected = false;
});
}
}

@override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: Stack(
fit: StackFit.expand,
children: <Widget>[
SingleChildScrollView(
child: Container(
height: AppTheme.fullHeight(context) — 50,
decoration: BoxDecoration(
gradient: LinearGradient(
colors: [
Color(0xfffbfbfb),
Color(0xfff7f7f7),
],
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
_appBar(),
_title(),
Expanded(
child: AnimatedSwitcher(
duration: Duration(milliseconds: 300),
switchInCurve: Curves.easeInToLinear,
switchOutCurve: Curves.easeOutBack,
child: isHomePageSelected
? MyHomePage()
: Align(
alignment: Alignment.topCenter,
child: ShoppingCartPage(),
),
),
)
],
),
),
),
Positioned(
bottom: 0,
right: 0,
child: CustomBottomNavigationBar(
onIconPresedCallback: onBottomIconPressed,
),
)
],
),
),
);
}
}
import ‘package:flutter/material.dart’;
import ‘package:flutter_ecommerce_app/src/model/data.dart’;
import ‘package:flutter_ecommerce_app/src/themes/light_color.dart’;
import ‘package:flutter_ecommerce_app/src/themes/theme.dart’;
import ‘package:flutter_ecommerce_app/src/widgets/title_text.dart’;
import ‘package:flutter_ecommerce_app/src/widgets/extentions.dart’;

class ProductDetailPage extends StatefulWidget {
ProductDetailPage({Key key}) : super(key: key);

@override
_ProductDetailPageState createState() => _ProductDetailPageState();
}

class _ProductDetailPageState extends State<ProductDetailPage>
with TickerProviderStateMixin {
AnimationController controller;
Animation<double> animation;
@override
void initState() {
super.initState();
controller =
AnimationController(vsync: this, duration: Duration(milliseconds: 300));
animation = Tween<double>(begin: 0, end: 1).animate(
CurvedAnimation(parent: controller, curve: Curves.easeInToLinear));
controller.forward();
}

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

bool isLiked = true;
Widget _appBar() {
return Container(
padding: AppTheme.padding,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
_icon(
Icons.arrow_back_ios,
color: Colors.black54,
size: 15,
padding: 12,
isOutLine: true,
onPressed: () {
Navigator.of(context).pop();
},
),
_icon(isLiked ? Icons.favorite : Icons.favorite_border,
color: isLiked ? LightColor.red : LightColor.lightGrey,
size: 15,
padding: 12,
isOutLine: false, onPressed: () {
setState(() {
isLiked = !isLiked;
});
}),
],
),
);
}

Widget _icon(
IconData icon, {
Color color = LightColor.iconColor,
double size = 20,
double padding = 10,
bool isOutLine = false,
Function onPressed,
}) {
return Container(
height: 40,
width: 40,
padding: EdgeInsets.all(padding),
// margin: EdgeInsets.all(padding),
decoration: BoxDecoration(
border: Border.all(
color: LightColor.iconColor,
style: isOutLine ? BorderStyle.solid : BorderStyle.none),
borderRadius: BorderRadius.all(Radius.circular(13)),
color:
isOutLine ? Colors.transparent : Theme.of(context).backgroundColor,
boxShadow: <BoxShadow>[
BoxShadow(
color: Color(0xfff8f8f8),
blurRadius: 5,
spreadRadius: 10,
offset: Offset(5, 5)),
],
),
child: Icon(icon, color: color, size: size),
).ripple(() {
if (onPressed != null) {
onPressed();
}
}, borderRadius: BorderRadius.all(Radius.circular(13)));
}

Widget _productImage() {
return AnimatedBuilder(
builder: (context, child) {
return AnimatedOpacity(
duration: Duration(milliseconds: 500),
opacity: animation.value,
child: child,
);
},
animation: animation,
child: Stack(
alignment: Alignment.bottomCenter,
children: <Widget>[
TitleText(
text: “AIP”,
fontSize: 160,
color: LightColor.lightGrey,
),
Image.asset(‘assets/show_1.png’)
],
),
);
}

Widget _categoryWidget() {
return Container(
margin: EdgeInsets.symmetric(vertical: 0),
width: AppTheme.fullWidth(context),
height: 80,
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.center,
children:
AppData.showThumbnailList.map((x) => _thumbnail(x)).toList()),
);
}

Widget _thumbnail(String image) {
return AnimatedBuilder(
animation: animation,
// builder: null,
builder: (context, child) => AnimatedOpacity(
opacity: animation.value,
duration: Duration(milliseconds: 500),
child: child,
),
child: Container(
margin: EdgeInsets.symmetric(horizontal: 10),
child: Container(
height: 40,
width: 50,
decoration: BoxDecoration(
border: Border.all(
color: LightColor.grey,
),
borderRadius: BorderRadius.all(Radius.circular(13)),
// color: Theme.of(context).backgroundColor,
),
child: Image.asset(image),
).ripple(() {}, borderRadius: BorderRadius.all(Radius.circular(13))),
),
);
}

Widget _detailWidget() {
return DraggableScrollableSheet(
maxChildSize: .8,
initialChildSize: .53,
minChildSize: .53,
builder: (context, scrollController) {
return Container(
padding: AppTheme.padding.copyWith(bottom: 0),
decoration: BoxDecoration(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(40),
topRight: Radius.circular(40),
),
color: Colors.white),
child: SingleChildScrollView(
controller: scrollController,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.max,
children: <Widget>[
SizedBox(height: 5),
Container(
alignment: Alignment.center,
child: Container(
width: 50,
height: 5,
decoration: BoxDecoration(
color: LightColor.iconColor,
borderRadius: BorderRadius.all(Radius.circular(10))),
),
),
SizedBox(height: 10),
Container(
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
TitleText(text: “NIKE AIR MAX 200”, fontSize: 25),
Column(
crossAxisAlignment: CrossAxisAlignment.end,
children: <Widget>[
Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
TitleText(
text: “\$ “,
fontSize: 18,
color: LightColor.red,
),
TitleText(
text: “240”,
fontSize: 25,
),
],
),
Row(
children: <Widget>[
Icon(Icons.star,
color: LightColor.yellowColor, size: 17),
Icon(Icons.star,
color: LightColor.yellowColor, size: 17),
Icon(Icons.star,
color: LightColor.yellowColor, size: 17),
Icon(Icons.star,
color: LightColor.yellowColor, size: 17),
Icon(Icons.star_border, size: 17),
],
),
],
),
],
),
),
SizedBox(
height: 20,
),
_availableSize(),
SizedBox(
height: 20,
),
_availableColor(),
SizedBox(
height: 20,
),
_description(),
],
),
),
);
},
);
}

Widget _availableSize() {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
TitleText(
text: “Available Size”,
fontSize: 14,
),
SizedBox(height: 20),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
_sizeWidget(“US 6”),
_sizeWidget(“US 7”, isSelected: true),
_sizeWidget(“US 8”),
_sizeWidget(“US 9”),
],
)
],
);
}

Widget _sizeWidget(String text,
{Color color = LightColor.iconColor, bool isSelected = false}) {
return Container(
padding: EdgeInsets.all(10),
decoration: BoxDecoration(
border: Border.all(
color: LightColor.iconColor,
style: !isSelected ? BorderStyle.solid : BorderStyle.none),
borderRadius: BorderRadius.all(Radius.circular(13)),
color:
isSelected ? LightColor.orange : Theme.of(context).backgroundColor,
),
child: TitleText(
text: text,
fontSize: 16,
color: isSelected ? LightColor.background : LightColor.titleTextColor,
),
).ripple(() {}, borderRadius: BorderRadius.all(Radius.circular(13)));
}

Widget _availableColor() {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
TitleText(
text: “Available Size”,
fontSize: 14,
),
SizedBox(height: 20),
Row(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
_colorWidget(LightColor.yellowColor, isSelected: true),
SizedBox(
width: 30,
),
_colorWidget(LightColor.lightBlue),
SizedBox(
width: 30,
),
_colorWidget(LightColor.black),
SizedBox(
width: 30,
),
_colorWidget(LightColor.red),
SizedBox(
width: 30,
),
_colorWidget(LightColor.skyBlue),
],
)
],
);
}

Widget _colorWidget(Color color, {bool isSelected = false}) {
return CircleAvatar(
radius: 12,
backgroundColor: color.withAlpha(150),
child: isSelected
? Icon(
Icons.check_circle,
color: color,
size: 18,
)
: CircleAvatar(radius: 7, backgroundColor: color),
);
}

Widget _description() {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
TitleText(
text: “Available Size”,
fontSize: 14,
),
SizedBox(height: 20),
Text(AppData.description),
],
);
}

FloatingActionButton _flotingButton() {
return FloatingActionButton(
onPressed: () {},
backgroundColor: LightColor.orange,
child: Icon(Icons.shopping_basket,
color: Theme.of(context).floatingActionButtonTheme.backgroundColor),
);
}

@override
Widget build(BuildContext context) {
return Scaffold(
floatingActionButton: _flotingButton(),
body: SafeArea(
child: Container(
decoration: BoxDecoration(
gradient: LinearGradient(
colors: [
Color(0xfffbfbfb),
Color(0xfff7f7f7),
],
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
)),
child: Stack(
children: <Widget>[
Column(
children: <Widget>[
_appBar(),
_productImage(),
_categoryWidget(),
],
),
_detailWidget()
],
),
),
),
);
}
}

Git Hub Link-

For More Information-

Thank You For Your Time….!!!

--

--

Sandeep Kumar Patel

Passionate about AI and ML, I see research as purposeful curiosity. Eager for feedback, email -" patelsandeep88@gmail.com"