Skip to content

Instantly share code, notes, and snippets.

@shashwat-kalpvaig
Created July 6, 2018 20:01
Show Gist options
  • Save shashwat-kalpvaig/e2ea92c2f376e25c09e0bddbd8163a96 to your computer and use it in GitHub Desktop.
Save shashwat-kalpvaig/e2ea92c2f376e25c09e0bddbd8163a96 to your computer and use it in GitHub Desktop.
import 'dart:async';
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'package:geolocation/geolocation.dart';
import 'package:geocoder/geocoder.dart';
import 'product_model.dart';
class DataQuery extends StatefulWidget {
@override
DataQueryState createState() => new DataQueryState();
}
class DataQueryState extends State<DataQuery> {
//all the variable are initialized here
int totalPrice = 0;
List data;
int total = 0;
String totalAmount;
var totalItemCount;
StreamSubscription<LocationResult> streamSubscription;
bool trackLocation = false;
List<Address> addressResults;
bool isLoading = false;
var locationName;
var address;
List<Product> productResult;
List<int> counterValue;
Product product;
//initializing the initstate() function to call gps check and start location finding function
@override
initState() {
super.initState();
//starting to get the methods which provide data to topBar and body of the application
this.getTopData();
this.getData();
}
//method/function to getData for the body
//or the each category user clicks
//TO DO the implementation for clicks
//right now just for a single api
Future<List> getData() async {
var response = await http.get(
//using a dummy api
Uri.encodeFull("https://jsonplaceholder.typicode.com/users"),
headers: {"Accept": "application/json"});
const JsonCodec json = const JsonCodec();
data = json.decode(response.body);
counterValues = new List<int>(data.length);
for(int i=0;i<counterValues.length;i++){
//initialise with 0 count for each service
counterValues[i]=0;
}
//creating the value for itemcount so that we can extract the details
//on each index by using totalItemCount
totalItemCount = data.length;
productResult = data.map((item) => new Product.fromJson(item)).toList();
return data;
}
//same as above
//but this method is to get data for top bar
//i.e the categories
Future<List> getTopData() async {
var response = await http.get(
Uri.encodeFull("https://jsonplaceholder.typicode.com/users"),
headers: {"Accept": "application/json"});
const JsonCodec json = const JsonCodec();
data = json.decode(response.body);
//totalItemCount = data.length;
return data;
}
@override
Widget build(BuildContext context) {
//creating the topBar after getting whole data using the future builder
final topBarView = FutureBuilder<List>(
future: getTopData(),
builder: (BuildContext context, AsyncSnapshot<List> snapshot) {
switch (snapshot.connectionState) {
case ConnectionState.none:
return Text('Loading');
case ConnectionState.waiting:
return Container(
child: Center(
child: Text('Loading'),
),
);
default:
if (snapshot.hasError)
return Text('Error');
else
//if we get data successfully then
return Center(
child: ListView(
children: <Widget>[
Container(
height: 50.0,
child: ListView(
scrollDirection: Axis.horizontal,
children: List.generate(snapshot.data.length,
(int index) {
return Card(
child: Container(
alignment: Alignment.center,
width: 80.0,
height: 50.0,
child: Text(
snapshot.data[index]['id'].toString()),
),
);
})),
)
],
),
);
}
});
//this is to create the UI for the body
final dataView = Container(
child: new FutureBuilder<List>(
//calling the getData() function to get the dtaa for the body from API
future: getData(),
//this is passed to snapshot
builder: (BuildContext context, AsyncSnapshot<List> snapshot) {
switch (snapshot.connectionState) {
//checking if data is none or coming then show progress Indicator
case ConnectionState.none:
case ConnectionState.waiting:
return new Container(
child: Center(
child: CircularProgressIndicator(),
),
);
//if there was any error in getting data
//print
default:
if (snapshot.hasError)
return new Text('Error:');
else
//this will fetch data and put in the UI
//main view which will be build fetching data from the url json
return new ListView.builder(
itemCount: totalItemCount,
itemBuilder: (BuildContext context, int index) =>
//main container for each of the product or service
//it will hold child data containers
Card(
margin: EdgeInsets.all(10.0),
color: Colors.lightBlueAccent,
child: Container(
height: 150.0,
//container is divided into two rows
//one to show details like name, price and detail of service
//second row will show the quantity
child: Row(
children: <Widget>[
//expanded widget to completely expand the rows
//first expanded has more space by
//giving more flex
Expanded(
flex: 3,
//container inside the first row to show
//name of the service
//below is its ui and fetching of name from json data
child: Container(
margin: EdgeInsets.all(20.0),
alignment: Alignment.centerLeft,
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Container(
alignment: Alignment.centerLeft,
margin: EdgeInsets.only(bottom: 10.0),
//the name of product
child: Text(
productResult[index].name,
style: TextStyle(
fontSize: 20.0,
color: Colors.black,
fontWeight: FontWeight.bold),
),
),
//this container shows the details of the services
//below is ui and fetching of the details
Container(
alignment: Alignment.centerLeft,
margin: EdgeInsets.only(bottom: 10.0),
child: Text(
productResult[index].featured_img,
style:
TextStyle(color: Colors.black87),
),
),
//sized box widget to create little space betweeen the price and details
//can also use margin but duh!!
SizedBox(
height: 10.0,
),
//third and last widget inside the row
//which is used to show the price fetched from json above
//and shown here
Container(
alignment: Alignment.centerLeft,
child: Text(
productResult[index].description,
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 16.0,
color: Colors.blueGrey),
),
),
],
),
)),
//this is the second expanded for the second row
Expanded(
flex: 1,
//container making second rowcounterValues
//it will contain add, remove and quantity colums
child: Container(
height: 150.0,
margin: EdgeInsets.all(10.0),
//center widget to center the colums
child: Center(
//column widget to create new widgets in column inside the row
child: Column(
children: <Widget>[
//first column is the container which consist add button
Container(
margin: EdgeInsets.only(bottom: 5.0),
//icon button to click for quantity
child: IconButton(
icon: Icon(
Icons.add_circle_outline,
),
onPressed: () {
total = total + snapshot.data[index]['id'];
totalAmount = total.toString();
counterValues[index] = counterValues[index]+1;
//here i am using setState(){ } to reload for specific card
//to update the text widgets value from line 334
//creating bottomSheet so that whenever the button is clicked
//the quantity is reflected on it
showBottomSheet<void>(
context: context,
builder: (BuildContext context) {
//bottomSheet consist of two rows
//one to shows selected items
//one with checkout button
return Container(
height: 200.0,
child: new Padding(
padding: const EdgeInsets.all(20.0),
child: Row(
//first row to show the item count
children: <Widget>[
Expanded(
flex: 2,
child: Text(
'Your total is $totalAmount ',
textAlign:
TextAlign
.center,
style: new TextStyle(
color: Theme
.of(
context)
.accentColor,
fontSize:
18.0)),
),
//second row to show the checkout button
Expanded(
flex: 1,
child:
RaisedButton(
child: Text(
'Check Out',
style: TextStyle(
fontSize:
16.0),
),
onPressed:
() {},
),
)
],
)));
});
},
),
),
//this is container which will show the item count on selecting add and remove
//need to change it to be dynamic
// Container(
// margin: EdgeInsets.only(bottom: 5.0),
// child: Text('$count', ),
// ),
//this is third column to show the remove button
//and then same functionality as add button
Container(
margin: EdgeInsets.only(bottom: 5.0),
child: IconButton(
icon: Icon(
Icons.remove_circle_outline,
),
onPressed: () {
total = total -
snapshot.data[index]['id'];
totalAmount = total.toString();
showBottomSheet<void>(
context: context,
builder:
(BuildContext context) {
return new Container(
child: new Padding(
padding:
const EdgeInsets
.all(20.0),
child: Row(
children: <
Widget>[
Expanded(
flex: 2,
child: Text(
'Your total is $totalAmount',
textAlign:
TextAlign
.center,
style: new TextStyle(
color: Theme
.of(
context)
.accentColor,
fontSize:
18.0)),
),
Expanded(
flex: 1,
child:
RaisedButton(
child: Text(
'Check Out',
style: TextStyle(
fontSize:
16.0),
),
onPressed:
() {},
),
)
],
)));
});
},
),
),
],
),
)),
)
],
),
),
),
);
}
},
));
//returning the final view by adding it into the body
return new Scaffold(
//safe area so that body remains below the status bar
body: SafeArea(
//to put all content in centre of screen
child: Center(
//main container inside cenntre
child: Container(
//created column for each top bar and body data
child: Column(
children: <Widget>[
//this is for top bar
//this expanded is the one holding location and the category of the services
Expanded(
flex: 1,
child: Container(
width: double.infinity,
child: Column(
children: <Widget>[
SizedBox(
height: 10.0,
),
//this container is being used to put the top bar view
Container(
height: 50.0,
child: topBarView,
),
],
),
),
),
//below top bar another expanded
//this shows the data/products
Expanded(
flex: 7,
child: Container(
child: dataView,
),
)
],
))),
),
);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment