I am making a simple weather application, with the OpenWeather API, and it throws me the following error:
"The following _CastError was thrown building FutureBuilder(dirty, state: _FutureBuilderState#9133d): type '_Type' is not a subtype of type 'Weather?' in type cast"
The Code is the following:
Future getForecast(Location location) async {
Forecast forecast;
String apiKey = "117bf0ee07134176cf271f0ad49f3807";
String lat = location.lat;
String lon = location.lon;
var url =
"https://api.openweathermap.org/data/2.5/onecall?lat=$lat&lon=$lon&appid=$apiKey&units=metric";
final response = await http.get(Uri.parse(url));
if (response.statusCode == 200) {
forecast = Forecast.fromJson(jsonDecode(response.body));
}
return _forecast;
}
class _forecast {
}
This is my complete code:
class CurrentWeatherPage extends StatefulWidget {
final List<Location> locations;
final BuildContext context;
const CurrentWeatherPage(this.locations, this.context);
#override
_CurrentWeatherPageState createState() =>
_CurrentWeatherPageState(this.locations, this.context);
}
class _CurrentWeatherPageState extends State<CurrentWeatherPage> {
final List<Location> locations;
Location location;
final BuildContext context;
_CurrentWeatherPageState(List<Location> locations, BuildContext context)
: this.locations = locations,
this.context = context,
this.location = locations[0];
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Color.fromRGBO(241, 254, 252, 1),
appBar: AppBar(
title: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
"Datos ",
style: TextStyle(fontSize: 22),
),
Text(
"Meteorológicos",
style: TextStyle(fontSize: 22, color: Color.fromRGBO(56, 215, 199, 1)),
)
],
),
backgroundColor: Color.fromRGBO(10, 45, 66, 0.9),
),
body: ListView(children: <Widget>[
currentWeatherViews(this.locations, this.location, this.context),
forcastViewsHourly(this.location),
forcastViewsDaily(this.location),
]),
);
}
void _changeLocation(Location newLocation) {
setState(() {
location = newLocation;
});
}
Widget currentWeatherViews(
List<Location> locations, Location location, BuildContext context) {
Weather? _weather;
return FutureBuilder(
builder: (context, snapshot) {
if (snapshot.hasData) {
_weather = snapshot.data as Weather?;
if (_weather == null) {
return Text("Error getting weather");
} else {
return Column(children: [
createAppBar(locations, location, context),
// CityDropDown(locations),
weatherBox(_weather!),
weatherDetailsBox(_weather!),
]);
}
} else {
return Center(child: CircularProgressIndicator());
}
},
future: getCurrentWeather(location),
);
}
Widget forcastViewsHourly(Location location) {
Forecast? _forcast;
return FutureBuilder(
builder: (context, snapshot) {
if (snapshot.hasData) {
_forcast = snapshot.data as Forecast?;
if (_forcast == null) {
return Text("Error getting weather");
} else {
return hourlyBoxes(_forcast!);
}
} else {
return Center(child: CircularProgressIndicator());
}
},
future: getForecast(location),
);
}
Widget forcastViewsDaily(Location location) {
Forecast? _forcast;
return FutureBuilder(
builder: (context, snapshot) {
if (snapshot.hasData) {
_forcast = snapshot.data as Forecast?;
if (_forcast == null) {
return Text("Error getting weather");
} else {
return dailyBoxes(_forcast!);
}
} else {
return Center(child: CircularProgressIndicator());
}
},
future: getForecast(location),
);
}
Widget createAppBar(
List<Location> locations, Location location, BuildContext context) {
// Location dropdownValue = locations.first;
return Container(
padding:
const EdgeInsets.only(left: 20, top: 15, bottom: 15, right: 20),
margin: const EdgeInsets.only(
top: 35, left: 15.0, bottom: 15.0, right: 15.0),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.all(Radius.circular(60)),
boxShadow: [
BoxShadow(
color: Colors.grey.withOpacity(0.1),
spreadRadius: 5,
blurRadius: 7,
offset: Offset(0, 3),
)
]),
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
DropdownButton<Location>(
value: location,
icon: Icon(
Icons.keyboard_arrow_down_rounded,
color: Colors.black,
size: 24.0,
semanticLabel: 'Tap to change location',
),
elevation: 16,
underline: Container(
height: 0,
color: Color.fromRGBO(10, 45, 66, 0.9),
),
onChanged: (newLocation) {
// callback(newValue);
// setState(() {
// location = newValue;
// });
var changeLocation = newLocation;
},
items:
locations.map<DropdownMenuItem<Location>>((Location value) {
return DropdownMenuItem<Location>(
value: value,
child: Text.rich(
TextSpan(
children: <TextSpan>[
TextSpan(
text: '${value.city.capitalizeFirstOfEach}, ',
style: TextStyle(
fontWeight: FontWeight.bold, fontSize: 16)),
TextSpan(
text: '${value.country.capitalizeFirstOfEach}',
style: TextStyle(
fontWeight: FontWeight.normal, fontSize: 16)),
],
),
),
);
}).toList(),
),
],
));
}
Widget weatherDetailsBox(Weather _weather) {
return Container(
padding: const EdgeInsets.only(left: 15, top: 25, bottom: 25, right: 15),
margin: const EdgeInsets.only(left: 15, top: 5, bottom: 15, right: 15),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.all(Radius.circular(20)),
boxShadow: [
BoxShadow(
color: Colors.grey.withOpacity(0.1),
spreadRadius: 5,
blurRadius: 7,
offset: Offset(0, 3),
)
]),
child: Row(
children: [
Expanded(
child: Column(
children: [
Container(
child: Text(
"Viento",
textAlign: TextAlign.left,
style: TextStyle(
fontWeight: FontWeight.w600,
fontSize: 12,
color: Colors.grey),
)),
Container(
child: Text(
"${_weather.wind} km/h",
textAlign: TextAlign.left,
style: TextStyle(
fontWeight: FontWeight.w700,
fontSize: 15,
color: Colors.black),
))
],
)),
Expanded(
child: Column(
children: [
Container(
child: Text(
"Humedad",
textAlign: TextAlign.left,
style: TextStyle(
fontWeight: FontWeight.w600,
fontSize: 12,
color: Colors.grey),
)),
Container(
child: Text(
"${_weather.humidity.toInt()}%",
textAlign: TextAlign.left,
style: TextStyle(
fontWeight: FontWeight.w700,
fontSize: 15,
color: Colors.black),
))
],
)),
Expanded(
child: Column(
children: [
Container(
child: Text(
"Presión atmosférica",
textAlign: TextAlign.left,
style: TextStyle(
fontWeight: FontWeight.w600,
fontSize: 12,
color: Colors.black45),
)),
Container(
child: Text(
"${_weather.pressure} hPa",
textAlign: TextAlign.left,
style: TextStyle(
fontWeight: FontWeight.w700,
fontSize: 15,
color: Colors.black),
))
],
))
],
),
);
}
Widget weatherBox(Weather _weather) {
return Stack(children: [
Container(
padding: const EdgeInsets.all(15.0),
margin: const EdgeInsets.all(15.0),
height: 160.0,
decoration: BoxDecoration(
color: Color.fromRGBO(55, 187, 174, 1),
borderRadius: BorderRadius.all(Radius.circular(20))),
),
ClipPath(
clipper: Clipper(),
child: Container(
padding: const EdgeInsets.all(15.0),
margin: const EdgeInsets.all(15.0),
height: 160.0,
decoration: BoxDecoration(
color: Color.fromRGBO(198, 9, 125, 1),
borderRadius: BorderRadius.all(Radius.circular(20))))),
Container(
padding: const EdgeInsets.all(15.0),
margin: const EdgeInsets.all(15.0),
height: 160.0,
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(20))),
child: Row(
children: [
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: <Widget>[
getWeatherIcon(_weather.icon),
Container(
margin: const EdgeInsets.all(5.0),
child: Text(
"${_weather.description.capitalizeFirstOfEach}",
style: TextStyle(
fontWeight: FontWeight.normal,
fontSize: 16,
color: Colors.white),
)),
Container(
margin: const EdgeInsets.all(5.0),
child: Text(
"Máxima:${_weather.high.toInt()}° Mínima:${_weather.low.toInt()}°",
textAlign: TextAlign.left,
style: TextStyle(
fontWeight: FontWeight.normal,
fontSize: 13,
color: Colors.white),
)),
])),
Column(children: <Widget>[
Container(
child: Text(
"${_weather.temp.toInt()}°",
textAlign: TextAlign.left,
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 60,
color: Colors.white),
)),
Container(
margin: const EdgeInsets.all(0),
child: Text(
"Sensación térmica ${_weather.feelsLike.toInt()}°",
textAlign: TextAlign.left,
style: TextStyle(
fontWeight: FontWeight.normal,
fontSize: 13,
color: Colors.white),
)),
])
],
))
]);
}
Image getWeatherIcon(String _icon) {
String path = 'assets/icons/';
String imageExtension = ".png";
return Image.asset(
path + _icon + imageExtension,
width: 70,
height: 70,
);
}
Image getWeatherIconSmall(String _icon) {
String path = 'assets/icons/';
String imageExtension = ".png";
return Image.asset(
path + _icon + imageExtension,
width: 40,
height: 40,
);
}
Widget hourlyBoxes(Forecast _forecast) {
return Container(
margin: EdgeInsets.symmetric(vertical: 0.0),
height: 150.0,
child: ListView.builder(
padding:
const EdgeInsets.only(left: 8, top: 0, bottom: 0, right: 8),
scrollDirection: Axis.horizontal,
itemCount: _forecast.hourly.length,
itemBuilder: (BuildContext context, int index) {
return Container(
padding: const EdgeInsets.only(
left: 10, top: 15, bottom: 15, right: 10),
margin: const EdgeInsets.all(5),
decoration: BoxDecoration(
color: Color.fromRGBO(1, 68, 109, 1),
borderRadius: BorderRadius.all(Radius.circular(18)),
boxShadow: [
BoxShadow(
color: Colors.grey.withOpacity(0.1),
spreadRadius: 2,
blurRadius: 2,
offset: Offset(0, 1), // changes position of shadow
)
]),
child: Column(children: [
Text(
"${_forecast.hourly[index].temp}°",
style: TextStyle(
fontWeight: FontWeight.w500,
fontSize: 17,
color: Color.fromRGBO(56, 215, 199, 1)),
),
getWeatherIcon(_forecast.hourly[index].icon),
Text(
"${getTimeFromTimestamp(_forecast.hourly[index].dt)}",
style: TextStyle(
fontWeight: FontWeight.w600,
fontSize: 12,
color: Colors.white),
),
]));
}));
}
String getTimeFromTimestamp(int timestamp) {
var date = new DateTime.fromMillisecondsSinceEpoch(timestamp * 1000);
var formatter = new DateFormat('h:mm a');
return formatter.format(date);
}
String getDateFromTimestamp(int timestamp) {
var date = new DateTime.fromMillisecondsSinceEpoch(timestamp * 1000);
var formatter = new DateFormat('E');
return formatter.format(date);
}
Widget dailyBoxes(Forecast _forcast) {
return Expanded(
child: ListView.builder(
shrinkWrap: true,
physics: ClampingScrollPhysics(),
padding:
const EdgeInsets.only(left: 8, top: 0, bottom: 0, right: 8),
itemCount: _forcast.daily.length,
itemBuilder: (BuildContext context, int index) {
return Container(
decoration: BoxDecoration(
color: Color.fromRGBO(1, 68, 109, 1),
borderRadius: BorderRadius.circular(10),
),
padding: const EdgeInsets.only(
left: 10, top: 5, bottom: 5, right: 10),
margin: const EdgeInsets.all(5),
child: Row(children: [
Expanded(
child: Text(
"${getDateFromTimestamp(_forcast.daily[index].dt)}",
style: TextStyle(fontSize: 14, color: Color.fromRGBO(56, 215, 199, 1)),
)),
Expanded(
child: getWeatherIconSmall(_forcast.daily[index].icon)),
Expanded(
child: Text(
"${_forcast.daily[index].high.toInt()}/${_forcast.daily[index].low.toInt()}",
textAlign: TextAlign.right,
style: TextStyle(fontSize: 14, color: Colors.white),
)),
]));
}));
}
}
class Clipper extends CustomClipper<Path> {
#override
Path getClip(Size size) {
Path path = Path();
path.moveTo(0, size.height - 20);
path.quadraticBezierTo((size.width / 6) * 1, (size.height / 2) + 15,
(size.width / 3) * 1, size.height - 30);
path.quadraticBezierTo((size.width / 2) * 1, (size.height + 0),
(size.width / 3) * 2, (size.height / 4) * 3);
path.quadraticBezierTo((size.width / 6) * 5, (size.height / 2) - 20,
size.width, size.height - 60);
path.lineTo(size.width, size.height - 60);
path.lineTo(size.width, size.height);
path.lineTo(0, size.height);
path.close();
return path;
}
#override
bool shouldReclip(Clipper oldClipper) => false;
}
Future getCurrentWeather(Location location) async {
Weather weather;
String city = location.city;
String apiKey = "117bf0ee07134176cf271f0ad49f3807";
var url =
"https://api.openweathermap.org/data/2.5/weather?q=$city&appid=$apiKey&units=metric";
final response = await http.get(Uri.parse(url));
if (response.statusCode == 200) {
weather = Weather.fromJson(jsonDecode(response.body));
}
return _weather;
}
class _weather {
}
Future getForecast(Location location) async {
Forecast forecast;
String apiKey = "117bf0ee07134176cf271f0ad49f3807";
String lat = location.lat;
String lon = location.lon;
var url =
"https://api.openweathermap.org/data/2.5/onecall?lat=$lat&lon=$lon&appid=$apiKey&units=metric";
final response = await http.get(Uri.parse(url));
if (response.statusCode == 200) {
forecast = Forecast.fromJson(jsonDecode(response.body));
}
return _forecast;
}
class _forecast {
}
I'm new to this, and I've tried many ways, but I can't get it to work. I would be grateful if someone could tell me the error and how to solve it. Thank you!
In your getCurrentWeather method, you assign the return value of the API call to weather, a local variable, but then continue to return _weather, a class not a variable. I don't know why it compiles even, probably because you did not use proper types.
I'll clean up one of the methods, please do the same with all of them where you may have done this. This is how your method should look like:
Future<Weather?> getCurrentWeather(Location location) async {
String city = location.city;
String apiKey = "117bf0ee07134176cf271f0ad49f3807";
var url =
"https://api.openweathermap.org/data/2.5/weather?q=$city&appid=$apiKey&units=metric";
final response = await http.get(Uri.parse(url));
if (response.statusCode == 200) {
return Weather.fromJson(jsonDecode(response.body));
}
return null;
}
Just a few random other remarks: the future should be a state variable, not called recreated every time build is called. This will happen if you put the call int the FutureBuilder directly. You pass a BuildContext through your class hierarchy. You should not need that. Just remove it altogether.
Related
I am trying to load an image from Firebase Firestore in a Flutter app, but I am getting the following error message:
RangeError (index): Invalid value: Valid value range is empty: 0
,
model.thumbnailUrl[0] is where the error is coming
Here is the relevant code for the CategoryProductCard class where I'm trying to display the image:
import 'package:flutter/material.dart';
import 'package:user/Config/method.dart';
import 'package:user/model/item.dart';
import 'package:user/screens/product_page.dart';
import 'package:user/widgets/customTextWidget.dart';
class CategoryProductCard extends StatelessWidget {
final ItemModel model;
CategoryProductCard({this.model});
#override
Widget build(BuildContext context) {
// double discount1 = ((model.mrp.toDouble() - model.price.toDouble()) /
// model.mrp.toDouble()) *
// 100.0;
// int discount = discount1.toInt().ceil();
final size = MediaQuery.of(context).size;
return Container(
color: Colors.white,
padding: EdgeInsets.symmetric(horizontal: 0, vertical: 0),
width: MediaQuery.of(context).size.width,
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Padding(
padding: const EdgeInsets.only(left: 0.0, top: 0),
child: Stack(
children: [
Container(
decoration: BoxDecoration(
color: Colors.grey[100],
borderRadius: BorderRadius.circular(5)),
height: 250,
width: size.width * .48,
child: InkWell(
onTap: () {
Route route = MaterialPageRoute(
builder: (_) => ProductPage(itemModel: model));
Navigator.push(context, route);
},
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
// mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
ClipRRect(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(5),
topRight: Radius.circular(5)),
child: Image.network(
model.thumbnailUrl[0],
height: 150,
width: size.width * .48,
fit: BoxFit.fill,
),
),
Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
mainAxisSize: MainAxisSize.max,
children: [
SizedBox(
width: 5,
),
Padding(
padding: const EdgeInsets.only(
left: 5.0, right: 5, top: 8),
child: Text(
model.title,
overflow: TextOverflow.ellipsis,
maxLines: 2,
style: TextStyle(
fontSize: 14,
),
),
// child: CustomText(
// overflow: TextOverflow.ellipsis,
// text: model.title,
// size: 15,
// fontWeight: FontWeight.w600,
// ),
),
// RichText(
// text: new TextSpan(
// children: <TextSpan>[
// new TextSpan(
// text: 'MRP: ₹${model.price}',
// style: new TextStyle(
// color: Colors.grey[500],
// fontSize: 12,
// decoration: TextDecoration.lineThrough,
// ),
// ),
// ],
// ),
// ),
Padding(
padding: const EdgeInsets.only(top: 5, bottom: 5),
child: RichText(
text: new TextSpan(
children: <TextSpan>[
new TextSpan(
text: 'MRP: ₹${model.mrp}',
style: new TextStyle(
color: Colors.grey[500],
fontSize: 11,
decoration: TextDecoration.lineThrough,
),
),
],
),
),
),
RichText(
text: new TextSpan(
children: <TextSpan>[
new TextSpan(
text: 'Price: ',
style: new TextStyle(
fontSize: 12,
fontWeight: FontWeight.normal,
color: Colors.black87,
),
),
new TextSpan(
text: '₹ ${model.price}',
style: new TextStyle(
fontSize: 12,
fontWeight: FontWeight.bold,
color: Theme.of(context).primaryColor,
),
),
],
),
),
// Padding(
// padding: const EdgeInsets.only(left: 5.0, top: 0),
// child: CustomText(
// overflow: TextOverflow.ellipsis,
// text: model.longDescription,
// size: 12,
// )),
SizedBox(
height: 12,
),
],
),
// Padding(
// padding: const EdgeInsets.symmetric(horizontal: 5.0),
// child: Row(
// mainAxisAlignment: MainAxisAlignment.spaceBetween,
// children: [
// CustomText(
// text: '₹' + (model.price).toString(),
// color: Theme.of(context).primaryColor,
// size: 14,
// fontWeight: FontWeight.w500,
// ),
// Container(
// alignment: Alignment.center,
// height: 20,
// width: 60,
// decoration: BoxDecoration(
// borderRadius: BorderRadius.circular(5),
// color: Colors.red.withOpacity(.1)),
// child: CustomText(
// text: '₹' +
// (model.discount).toString() +
// ' Off',
// color: Theme.of(context).primaryColor,
// size: 12,
// fontWeight: FontWeight.normal,
// ),
// ),
// ],
// ),
// )
],
),
),
),
Positioned(
top: 10,
right: 10,
child: Container(
alignment: Alignment.center,
height: 35,
width: 35,
decoration: BoxDecoration(
shape: BoxShape.circle,
color: Colors.black.withOpacity(.65)),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
CustomText(
text: '${model.discount}%',
size: 10,
color: Colors.white,
),
CustomText(
text: 'OFF',
size: 10,
color: Colors.white,
),
],
),
),
)
],
),
),
],
),
);
}
}
Here is how i passed the model to the above code from different page
GridView.builder(
physics: NeverScrollableScrollPhysics(),
shrinkWrap: true,
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
crossAxisSpacing: 1,
childAspectRatio: .69),
itemBuilder: (context, index) {
ItemModel model;
if (dataSnapshot.hasData)
model = ItemModel.fromJson(
dataSnapshot.data.docs[index].data());
//debugPrint(dataSnapshot.data.documents.length.toString());
if (dataSnapshot.hasData)
return CategoryProductCard(
model: model,
);
else
return Text('No more products');
},
itemCount:
dataSnapshot != null ? dataSnapshot.data.docs.length : 0,
);
This is my data collection
import 'package:cloud_firestore/cloud_firestore.dart';
class ItemModel {
String category;
String details;
int discount;
bool isFeatured;
String longDescription;
int mrp;
String pid;
int price;
Timestamp publishedDate;
int quantity;
String shortInfo;
String status;
List thumbnailUrl;
String title;
ItemModel({
this.title,
this.shortInfo,
this.publishedDate,
this.thumbnailUrl,
this.longDescription,
this.status,
});
ItemModel.fromJson(Map<String, dynamic> json) {
category = json['category'];
details = json['details'];
discount = json['discount'];
isFeatured=json['isFeatured'];
longDescription = json['longDescription'];
mrp = json['mrp'];
pid = json['pid'];
price = json['price'];
publishedDate = json['publishedDate'];
quantity = int.parse(json['quantity']);
shortInfo = json['shortInfo'];
status = json['status'];
thumbnailUrl = json['thumbnailUrl'];
title = json['title'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['title'] = this.title;
data['shortInfo'] = this.shortInfo;
data['price'] = this.price;
if (this.publishedDate != null) {
data['publishedDate'] = this.publishedDate;
}
data['thumbnailUrl'] = this.thumbnailUrl;
data['longDescription'] = this.longDescription;
data['status'] = this.status;
data['details'] = this.details;
return data;
}
}
class PublishedDate {
String date;
PublishedDate({this.date});
PublishedDate.fromJson(Map<String, dynamic> json) {
date = json['$date'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['$date'] = this.date;
return data;
}
}
Model giving all the deatils except thumbUrl , Don't know why this is happening , Thanks in advance
That because thumbnailUrl is empty not valued yet.
You have to wait the Future that set the values on thumbnailUrl then setState to refresh the Widget.
However to avoid the error you can do something like that:
children: [
model.thumbnailUrl.length > 0 ?
ClipRRect(
borderRadius: BorderRadius.only(topLeft: Radius.circular(5), topRight: Radius.circular(5)),
child: Image.network(
model.thumbnailUrl[0],
height: 150,
width: size.width * .48,
fit: BoxFit.fill,
),
) : CircularProgressIndicator() ,
//.other widgets here
]
I am trying to create a list of items in flutter with listView.builder, i am also using using elevatedButton in my itemBuilder.
i applied setState in button
i want to change value of single item only
but that is applying to every value in list
here is my code
import 'dart:developer';
import 'package:counter_button/counter_button.dart';
import 'package:flutter/material.dart';
import 'package:fooddeliveryapp/apis.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';
import 'models/restrauntmenu.dart';
class RestrauntPage extends StatefulWidget {
final String restrauntId;
final String restrauntName;
final String restrauntType;
final String restrauntApproxBill;
final String restrauntTagline;
const RestrauntPage(
{Key? key,
required this.restrauntId,
required this.restrauntType,
required this.restrauntApproxBill,
required this.restrauntTagline,
required this.restrauntName})
: super(key: key);
#override
State<RestrauntPage> createState() => _RestrauntPageState();
}
class _RestrauntPageState extends State<RestrauntPage> {
int _counterValue = 1;
bool itemAdded = false;
late Future<List<RestrauntMenu>> futureRestrauntMenu;
Future<List<RestrauntMenu>> fetchRestrauntMenu() async {
String restrauntId = widget.restrauntId;
final response = await http.get(Uri.parse(menuApi(restrauntId)));
if (response.statusCode == 200) {
final parsed = json.decode(response.body).cast<Map<String, dynamic>>();
return parsed
.map<RestrauntMenu>((json) => RestrauntMenu.fromMap(json))
.toList();
} else {
throw Exception('Failed to load album');
}
}
addToCartButton(
{required String? itemname,
required String? itemprice,
required int? itemCount,
required String? usermob,
required String? restrauntName}) {
return ElevatedButton(
clipBehavior: Clip.antiAliasWithSaveLayer,
style: ButtonStyle(
elevation: MaterialStateProperty.all(
6,
),
backgroundColor: MaterialStateProperty.all(Colors.white),
),
onPressed: () {
addToCart(
itemname: itemname,
itemprice: itemprice,
restrauntName: restrauntName,
usermob: usermob,
itemCount: itemCount);
},
child: const Padding(
padding: EdgeInsets.all(8.0),
child: Text(
'ADD TO CART',
style: TextStyle(
color: Colors.green,
fontSize: 18,
fontWeight: FontWeight.bold,
),
),
),
);
}
counterButton() {
return Container(
decoration: const BoxDecoration(color: Colors.white),
child: CounterButton(
loading: false,
onChange: (int val) {
setState(() {
_counterValue = val;
});
},
count: _counterValue,
countColor: Colors.green,
buttonColor: Colors.black,
progressColor: Colors.black,
),
);
}
Future addToCart(
{required String? itemname,
required String? itemprice,
required int? itemCount,
required String? usermob,
required String? restrauntName}) async {
itemCount = _counterValue;
var url = addToCartApi(
itemname: itemname,
itemprice: itemprice,
itemCount: itemCount,
usermob: usermob,
restrauntName: restrauntName);
var response = await http.get(
Uri.parse(url),
);
if (response.statusCode == 200) {
setState(() {
itemAdded = true;
});
} else {
return false;
}
}
#override
void initState() {
futureRestrauntMenu = fetchRestrauntMenu();
super.initState();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
foregroundColor: Colors.black,
elevation: 0,
backgroundColor: Colors.white,
title: const Text('Restraunt Name'),
),
body: SingleChildScrollView(
child: SizedBox(
height: MediaQuery.of(context).size.height,
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
SizedBox(
width: MediaQuery.of(context).size.width * 0.03,
),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
widget.restrauntName,
style: const TextStyle(
color: Colors.black,
fontSize: 24,
fontWeight: FontWeight.w900,
),
),
// const SizedBox(height: 4),
Text(
widget.restrauntType,
style: const TextStyle(
color: Colors.black,
fontSize: 16,
fontWeight: FontWeight.normal,
),
),
Text(
widget.restrauntTagline,
style: const TextStyle(
color: Colors.black87,
fontSize: 12,
fontWeight: FontWeight.normal,
),
),
const SizedBox(
height: 6,
),
Container(
decoration: BoxDecoration(
color: Colors.grey[200],
borderRadius: BorderRadius.circular(10),
),
child: Padding(
padding: const EdgeInsets.all(8.0),
child: RichText(
text: TextSpan(
children: [
const WidgetSpan(
child: Icon(
Icons.currency_rupee,
size: 16,
color: Color.fromARGB(255, 45, 174, 49),
),
),
TextSpan(
text: widget.restrauntApproxBill,
style: const TextStyle(
color: Colors.black,
fontSize: 12,
fontWeight: FontWeight.bold,
),
),
],
),
),
),
),
],
),
const Spacer(),
Container(
decoration: BoxDecoration(
color: const Color.fromARGB(255, 49, 171, 53),
borderRadius: BorderRadius.circular(12),
),
child: Padding(
padding: const EdgeInsets.all(8.0),
child: RichText(
text: const TextSpan(
children: [
TextSpan(
text: '3.6',
style: TextStyle(
color: Colors.white,
fontSize: 16,
fontWeight: FontWeight.bold,
),
),
WidgetSpan(
child: Icon(
Icons.star,
color: Colors.white,
size: 18,
),
),
],
),
),
),
),
SizedBox(
width: MediaQuery.of(context).size.width * 0.03,
),
],
),
const SizedBox(
height: 12,
),
Expanded(
child: FutureBuilder<List<RestrauntMenu>>(
future: futureRestrauntMenu,
builder: (context, snapshot) {
if (snapshot.hasData) {
return ListView.builder(
itemCount: snapshot.data!.length,
itemBuilder: (context, index) {
return ExpansionTile(
initiallyExpanded: true,
childrenPadding: const EdgeInsets.all(8),
title: Text(
snapshot.data![index].catname!,
style: const TextStyle(
fontSize: 20, fontWeight: FontWeight.bold),
),
children: [
Row(
children: [
Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment:
CrossAxisAlignment.start,
children: [
Text(
snapshot.data![index].itemname!,
style: const TextStyle(
fontSize: 30,
fontWeight: FontWeight.bold,
),
),
const SizedBox(
height: 4,
),
Text(
snapshot.data![index].itemPrice!,
style: const TextStyle(
fontSize: 20,
fontWeight: FontWeight.w600,
),
),
const SizedBox(
height: 4,
),
Text(
snapshot.data![index].itemDescription!,
style: const TextStyle(
fontSize: 12,
fontWeight: FontWeight.normal,
),
),
],
),
const Spacer(),
Stack(
alignment: Alignment.bottomCenter,
children: [
Padding(
padding:
const EdgeInsets.only(bottom: 16),
child: ClipRRect(
borderRadius:
BorderRadius.circular(10),
child: FittedBox(
child: Container(
height: MediaQuery.of(context)
.size
.height *
0.22,
width: MediaQuery.of(context)
.size
.width *
0.4,
decoration: BoxDecoration(
color: Colors.red,
image: DecorationImage(
fit: BoxFit.cover,
image: NetworkImage(
'http://www.jfamoslogistics.com/images/${snapshot.data![index].itemimage!}',
),
),
),
),
),
),
),
Align(
alignment: Alignment.topRight,
child: itemAdded
? counterButton()
: addToCartButton(
itemprice: snapshot
.data![index].itemPrice,
itemname: snapshot
.data![index].itemname,
itemCount: _counterValue,
restrauntName:
widget.restrauntName,
usermob: '9354954343',
))
],
)
],
),
],
);
},
);
} else if (snapshot.hasError) {
return Text("${snapshot.error}");
}
return const Center(
child: CircularProgressIndicator(),
);
},
),
),
],
),
),
),
);
}
}
please check and help me
please let me know if i am missing something or making some mistake in code
i have tried google everywhere but nothing works
thanks in advance
As Giseppe Colucci described, you are using a single counter variable for a list . You can follow the simple approach of using list. On State
int _counterValue = 1; will be replaced with List<int> _counterValue = []
After getting data initialize the list with default value.
if (snapshot.hasData) {
_counterValue =List.generate(snapshot.data!.length, (index) => 1); // you might prefer default value as 0 instead of 1
As for the counter button method we need to update specific index, therefore we will pass index here
counterButton(int index) {
return Container(
decoration: const BoxDecoration(color: Colors.white),
child: CounterButton(
loading: false,
onChange: (int val) {
setState(() {
_counterValue[index] = val;
});
},
count: _counterValue[index],
Now whenever we use this counterButton method we need to pass index and here we get index from listview.
child: itemAdded
? counterButton(index)
: addToCartButton(
That is because your itemAdded bool is only one, for every item in the list, you should make a map, like this:
{'id':true}
where id is the restaurant menu item, and true is whenever the item is selected or not.
If this is too hard for you, just use a simple list.
I have 2 widgets ProfitDisplay() and BetListDisplay(), I want to be able to share data from a firestore query without calling the same query twice. For ProfitDisplay() I'll need at least 1 more stream. My current code queries the db twice once for each widget which is not very efficient. I tried wrapping ListView() with StreamProvider.value() but then I got an error saying it could not find the Provider.
The query is based on dates selected in the first widget in the ListView()
class DailyPage extends StatefulWidget {
const DailyPage({Key? key}) : super(key: key);
#override
_DailyPageState createState() => _DailyPageState();
}
class _DailyPageState extends State<DailyPage> {
final FirebaseAuth auth = FirebaseAuth.instance;
final DateTime now = DateTime.now();
final days = getWeekDayList;
int _currentWeekDayNameAndNum = getCurrentWeekDayInt();
final db = FirestoreService();
#override
Widget build(BuildContext context) {
int selectedDay = int.parse(days[_currentWeekDayNameAndNum]['day']);
final User? user = auth.currentUser;
DateTime startDate = DateTime(now.year, now.month, selectedDay, 00, 00);
DateTime endDate = DateTime(now.year, now.month, selectedDay, 23, 59);
return Scaffold(
backgroundColor: white.withOpacity(1),
body: ListView(
children: [
Column(
children: [
Container(
margin: const EdgeInsets.all(10),
decoration: BoxDecoration(color: white, boxShadow: [
BoxShadow(
color: grey.withOpacity(0.5),
spreadRadius: 4,
blurRadius: 5,
// changes position of shadow
),
]),
child: Padding(
padding: const EdgeInsets.only(
top: 10, right: 10, left: 10, bottom: 20),
child: Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: const [
Text(
"Daily Transactions",
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
color: black),
),
],
),
const SizedBox(
height: 25,
),
Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: List.generate(days.length, (index) {
return GestureDetector(
onTap: () {
setState(() {
_currentWeekDayNameAndNum = index;
});
},
child: SizedBox(
width:
(MediaQuery.of(context).size.width - 40) /
7,
child: Column(
children: [
Text(
days[index]['label'],
style: const TextStyle(fontSize: 10),
),
const SizedBox(
height: 10,
),
Container(
width: 30,
height: 30,
decoration: BoxDecoration(
color: _currentWeekDayNameAndNum ==
index
? primary
: Colors.transparent,
shape: BoxShape.circle,
border: Border.all(
color:
_currentWeekDayNameAndNum ==
index
? primary
: black
.withOpacity(0.1))),
child: Center(
child: Text(
days[index]['day'],
style: TextStyle(
fontSize: 10,
fontWeight: FontWeight.w600,
color:
_currentWeekDayNameAndNum ==
index
? white
: black),
),
),
)
],
),
),
);
}))
],
),
),
),
],
),
StreamProvider<List<BetData>>.value(
value: FirestoreService()
.streamBetDataBetweenDates(user!, startDate, endDate),
initialData: [],
child: const ProfitDisplay(),
),
const SizedBox(
height: 10,
),
StreamProvider<List<BetData>>.value(
value: FirestoreService()
.streamBetDataBetweenDates(user, startDate, endDate),
initialData: [],
child: const BetListDisplay(),
)
],
));
}
}
class _ProfitDisplayState extends State<ProfitDisplay> {
double _dailyTotal = 0;
#override
Widget build(BuildContext context) {
List betList = Provider.of<List<BetData>>(context);
double _total = 0;
for (var bet in betList) {
_total += bet.value;
}
_dailyTotal = _total;
return Container(
margin: const EdgeInsets.fromLTRB(8, 8, 8, 0),
decoration: BoxDecoration(color: white, boxShadow: [
BoxShadow(
color: grey.withOpacity(0.5),
spreadRadius: 4,
blurRadius: 5,
// changes position of shadow
),
]),
child: Container(
alignment: Alignment.center,
margin: const EdgeInsets.all(8),
child: _dailyTotal > 0
? Text(
'£ ${_dailyTotal.toString()}',
style: const TextStyle(
color: Colors.green,
fontSize: 25,
fontWeight: FontWeight.bold),
)
: Text(
'£ ${_dailyTotal.toString()}',
style: const TextStyle(
color: Colors.red,
fontSize: 25,
fontWeight: FontWeight.bold),
),
));
}
}
Not sure if it's relevant but here's FirestoreService()
class FirestoreService {
final FirebaseFirestore _db = FirebaseFirestore.instance;
/// List of bets between startDate and endData
Stream<List<BetData>> streamBetDataBetweenDates(
User user, DateTime startDate, DateTime endDate) {
var ref = _db
.collection('users/${user.uid}/bets')
.where('d', isGreaterThanOrEqualTo: startDate)
.where('d', isLessThanOrEqualTo: endDate)
.orderBy('d', descending: true);
print('this got called at ${DateTime.now()}');
return ref.snapshots().map(
(list) => list.docs.map((doc) => BetData.fromFirestore(doc)).toList());
}
}
when I am increasing my quantity of one product then all product's quantity is increasing, so how to solve it.
This is my product page:
import 'dart:convert';
import 'package:carousel_pro/carousel_pro.dart';
import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:hospital/Authentication/LoginLogoutScreenPage/login.dart';
import 'package:hospital/CartPage/Cart_Api/cart_api.dart';
import 'package:hospital/CartPage/pages/cartPage.dart';
import 'package:hospital/Drawer/dropdown_menu.dart';
import 'package:hospital/ProductDetailsPage/product_detailPage.dart';
import 'package:hospital/ProductDetailsPage/related_product_page.dart';
import 'package:hospital/SecondSection/Medicine/medicine_page.dart';
import 'package:hospital/constant.dart';
import 'package:hospital/customApiVariable.dart';
import 'package:http/http.dart' as http;
import 'package:line_icons/line_icons.dart';
import 'package:provider/provider.dart';
class DetailPage extends StatefulWidget {
final plistId;
const DetailPage({Key key, this.plistId}) : super(key: key);
#override
_DetailPageState createState() => _DetailPageState();
}
class _DetailPageState extends State<DetailPage> {
final GlobalKey<FormState> _formKey = GlobalKey();
int quantity = 1;
var response;
var detailPageApi;
#override
void initState() {
super.initState();
fetchData(widget.plistId);
}
fetchData(var consultWithDoctor) async {
var api = Uri.parse(
'$ecommerceBaseUrl/productListApi.php?a2rTokenKey=$a2rTokenKey&plistId=${widget.plistId}');
response = await http.get(
api,
);
print("detailPageApi " + api.toString());
print("detailPageBody " + response.body);
detailPageApi = jsonDecode(response.body);
print("detailPagelist " + detailPageApi.toString());
setState(() {});
}
Future _submit() async {
var errorMessage = 'Authentication Failed';
if (successfully_add_cart_status.toString() == 'false') {
errorMessage = 'Please try again later';
print(errorMessage);
_showerrorDialog(errorMessage);
} else {
errorMessage = 'Product Succesfully Added to Cart';
print(errorMessage);
_showerrorDialog(errorMessage);
}
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: kGreen,
title: Text(
"Details",
style: TextStyle(fontStyle: FontStyle.italic),
),
actions: [
IconButton(
icon: Icon(Icons.shopping_cart),
// onPressed: () => print("open cart"),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => Cartpage()),
);
},
),
DropDownMenu(),
],
),
body: Container(
child: response != null
? ListView.builder(
itemCount: detailPageApi.length.clamp(0, 1),
scrollDirection: Axis.vertical,
physics: ScrollPhysics(),
shrinkWrap: true,
itemBuilder: (context, index) {
var details = detailPageApi[index];
if (details['num'] == 0) {
return Center(
child: CircularProgressIndicator(
backgroundColor: Colors.white,
),
);
}
return Column(
children: <Widget>[
Hero(
tag: "1",
child: SizedBox(
height: 300.0,
width: 300.0,
child: Carousel(
boxFit: BoxFit.cover,
autoplay: false,
animationCurve: Curves.fastOutSlowIn,
animationDuration: Duration(milliseconds: 800),
dotSize: 6.0,
dotIncreasedColor: Colors.black,
dotBgColor: Colors.transparent,
// dotPosition: DotPosition.topRight,
dotVerticalPadding: 10.0,
showIndicator: true,
indicatorBgPadding: 7.0,
images: [
NetworkImage(details['pImgImg']),
],
),
),
),
SizedBox(
height: 50,
),
Padding(
padding: const EdgeInsets.only(left: 20, right: 20),
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
"Name :",
style: TextStyle(
fontSize: 18,
height: 1.5,
fontWeight: FontWeight.w500),
),
SizedBox(
width: 20,
),
Flexible(
child: Text(
// widget.details,
details['productName'],
style: TextStyle(
fontSize: 17,
height: 1.5,
fontWeight: FontWeight.w500),
),
),
],
),
),
SizedBox(
height: 20,
),
Padding(
padding: const EdgeInsets.only(left: 20, right: 20),
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
"Details :",
style: TextStyle(
fontSize: 18,
height: 1.5,
fontWeight: FontWeight.w500),
),
SizedBox(
width: 20,
),
Flexible(
child: Text(
// widget.details,
details['productDescription'],
style: TextStyle(
fontSize: 17,
height: 1.5,
fontWeight: FontWeight.w500),
),
),
],
),
),
SizedBox(
height: 20,
),
Padding(
padding: const EdgeInsets.only(left: 20, right: 20),
child: Row(
children: <Widget>[
Text(
"Price :",
style: TextStyle(
fontSize: 18, fontWeight: FontWeight.w500),
),
SizedBox(
width: 20,
),
Row(
children: <Widget>[
Text(
// "Rs " + widget.pPromotionPrice,
"Rs 55.0",
style: TextStyle(
fontSize: 17,
fontWeight: FontWeight.w500),
),
SizedBox(
width: 20,
),
Text(
// "Rs " + widget.pPrice,
"Rs 100",
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.w500,
// color: warning,
decoration: TextDecoration.lineThrough),
)
],
)
],
),
),
SizedBox(
height: 25,
),
Padding(
padding: const EdgeInsets.only(right: 20, left: 20),
child: Row(
children: <Widget>[
Text(
"Qty :",
style: TextStyle(
fontSize: 17, fontWeight: FontWeight.w500),
),
SizedBox(
width: 20,
),
Row(
children: <Widget>[
InkWell(
onTap: () {
if (quantity > 1) {
setState(() {
quantity = --quantity;
});
}
// minus here
},
child: Container(
width: 25,
height: 25,
decoration: BoxDecoration(
// border: Border.all(color: primary),
shape: BoxShape.circle),
child: Icon(
LineIcons.minus,
size: 15,
),
),
),
SizedBox(
width: 15,
),
Text(
quantity.toString(),
style: TextStyle(fontSize: 16),
),
SizedBox(
width: 15,
),
InkWell(
onTap: () {
setState(() {
quantity = ++quantity;
});
// minus here
},
child: Container(
width: 25,
height: 25,
decoration: BoxDecoration(
// border: Border.all(color: primary),
shape: BoxShape.circle),
child: Icon(
LineIcons.plus,
size: 15,
),
),
),
],
)
],
),
),
SizedBox(
height: 50,
),
InkWell(
onTap: () async {
if (var_uid.toString() != null.toString()) {
_submit();
var qty = quantity.toString();
var plistId = widget.plistId;
print('pplistid' + plistId);
var uid = var_uid.toString();
var sid = var_sid.toString();
print('uuid' + uid);
print('ssid' + sid);
var response =
await add_to_cart_fn(qty, plistId, uid, sid);
print("rsp: " + response['msg']);
} else {
Navigator.of(context).push(MaterialPageRoute(
builder: (context) => LoginPage()));
}
},
// },
child: Padding(
padding: EdgeInsets.only(left: 20, right: 20),
child: Container(
height: 45,
width: double.infinity,
decoration: BoxDecoration(
color: kGreen,
borderRadius: BorderRadius.circular(30)),
child: Center(
child: Text(
"ADD TO CART",
style: TextStyle(
color: kWhite,
fontSize: 20,
),
),
),
),
),
),
SizedBox(height: 20.0),
RelatedProductPage(plistId: widget.plistId)
],
);
})
: Center(
child: CircularProgressIndicator(
backgroundColor: Colors.white,
),
),
),
);
}
void _showerrorDialog(String message) {
Fluttertoast.showToast(
msg: message,
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.BOTTOM,
timeInSecForIosWeb: 1,
backgroundColor: Colors.grey[350],
textColor: Colors.black,
fontSize: 16.0);
}
}
You are using the same quantity variable against each item. Changing the value on one of those will cause all items to update. What you need to do is to keep a Map of quantity selected against product id. That way whenever you increase or decrease the quantity, you update the quantity against that specific product id and the rest will remain unchanged.
EDIT: Here is how this will work
//Create a new map to save the product id and product selected quantity
var productQuantity = new Map<int, int>()
//When setting the values of the product, set the quantity from the map
Padding(
padding: const EdgeInsets.only(right: 20, left: 20),
child: Row(
children: <Widget>[
Text(
"Qty :",
style: TextStyle(
fontSize: 17, fontWeight: FontWeight.w500),
),
SizedBox(width: 20,),
Row(
children: <Widget>[
InkWell(
onTap: () {
if (quantity > 1) {
setState(() {
//Changed here
productQuantity['$productId'] -= 1;
});
}
},
child: Container(
width: 25,
height: 25,
decoration: BoxDecoration(shape: BoxShape.circle),
child: Icon(
LineIcons.minus,
size: 15,
),
),
),
SizedBox(width: 15,),
Text(
//Changed here
productQuantity['$productId'].toString(),
style: TextStyle(fontSize: 16),
),
SizedBox(width: 15,),
InkWell(
onTap: () {
setState(() {
//Changed here
productQuantity['$productId'] += 1;
});
},
child: Container(
width: 25,
height: 25,
decoration: BoxDecoration(
shape: BoxShape.circle),
),
child: Icon(
LineIcons.plus,
size: 15,
),
),
),
],
)
],
),
)
you set the common quantity in all products so change it and set it inside the class.
Please Check the example
import 'package:flutter/material.dart';
class QuantityUpdatePage extends StatefulWidget {
#override
_QuantityUpdatePageState createState() => _QuantityUpdatePageState();
}
class _QuantityUpdatePageState extends State<QuantityUpdatePage> {
List<Product> productArray = [];
#override
void initState() {
super.initState();
WidgetsBinding.instance!.addPostFrameCallback((timeStamp) {
productArray.clear();
productArray.add(Product(1, "Product 1", 1));
productArray.add(Product(2, "Product 2", 1));
productArray.add(Product(3, "Product 3", 1));
productArray.add(Product(4, "Product 4", 1));
productArray.add(Product(5, "Product 5", 1));
setState(() {});
});
}
#override
void dispose() {
super.dispose();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("QUANTITY UPDATE")),
body: ListView.builder(
shrinkWrap: true,
itemCount: productArray.length,
itemBuilder: (context, index) {
return Padding(
padding: const EdgeInsets.only(right: 20, left: 20),
child: ListView(
shrinkWrap: true,
physics: NeverScrollableScrollPhysics(),
children: [
SizedBox(
height: 20,
),
Row(
mainAxisSize: MainAxisSize.min,
children: [
Text(productArray[index].productName),
SizedBox(
width: 40,
),
Row(
children: <Widget>[
Text(
"Qty :",
style: TextStyle(fontSize: 17, fontWeight: FontWeight.w500),
),
SizedBox(
width: 20,
),
Row(
children: <Widget>[
InkWell(
onTap: () {
if (productArray[index].quantity > 1) {
setState(() {
productArray[index].quantity = --productArray[index].quantity;
});
}
// minus here
},
child: Container(
width: 25,
height: 25,
decoration: BoxDecoration(
// border: Border.all(color: primary),
shape: BoxShape.circle),
child: Icon(
Icons.minimize,
size: 15,
),
),
),
SizedBox(
width: 15,
),
Text(
productArray[index].quantity.toString(),
style: TextStyle(fontSize: 16),
),
SizedBox(
width: 15,
),
InkWell(
onTap: () {
setState(() {
productArray[index].quantity = ++productArray[index].quantity;
});
// minus here
},
child: Container(
width: 25,
height: 25,
decoration: BoxDecoration(
// border: Border.all(color: primary),
shape: BoxShape.circle),
child: Icon(
Icons.add,
size: 15,
),
),
),
],
)
],
),
],
),
SizedBox(
height: 20,
),
],
),
);
}));
}
}
class Product {
String productName;
int quantity;
int id;
Product(this.id, this.productName, this.quantity);
}
#Deepak if you don't understand Maps use list instead, with a value being updated for each index. Initialize a list of int types with some large values like 1000000, and update the value for each index. use ListView builder to fetch the data from the API for each index.
List<int> quantity = List.empty(growable: true);
OR
List<int> quantity = List.filled(10000, []);
For updating quantity:-
quantity[index] += 1;
For Grid view thing, refer this example from CodeGrepper:-
GridView.count(
// Create a grid with 2 columns. If you change the scrollDirection to
// horizontal, this produces 2 rows.
crossAxisCount: 2,
// Generate 100 widgets that display their index in the List.
children: List.generate(100, (index) {
return Center(
child: Text(
'Item $index',
style: Theme.of(context).textTheme.headline5,
),
);
}),
);
I am having an issue getting data from the firebase realtime database in the tab bar view. Data showing in Tabbar view from real-time database flutter .. but last tab data same showing in all tabs. All the tab bar views data are different but it is showing data of one tab in all tabs. I think it overwrites previous data with data we got at last tab.
Screen Shot1
Screen Shot 2
loadsubcategories() {
ref = FirebaseDatabase.instance;
ref.reference().child('Categories').child(id).child("Subcategories")
// .onValue
// .listen((event) {
// var snapshot = event.snapshot;
.once()
.then((DataSnapshot snapshot){
if(snapshot.value != null){
var keys = snapshot.value.keys;
var value = snapshot.value;
//listtab = new List();
listtab.clear();
for (var key in keys) {
print(key);
TabNews data = TabNews(
value[key]['subcategory'],
0,
value[key]['id'],
);
listtab.add(data);
}
} else {
print("chal Chutti kr");
}
// setState(() {
//
// });
setState(() {
// _controller = TabController( length: listtab.length, initialIndex: 0);
// _controller.addListener(_handleTabSelection);
});
}
);
}
tabbarviewdata(String subcategoryid) {
print("fajasl"+id);
cardref = FirebaseDatabase.instance;
cardref.reference().child('Categories').child(id).child("Subcategories").child(subcategoryid).child("Personalities")
// .onValue
// .listen((event) {
// var snapshot = event.snapshot;
.once()
.then((DataSnapshot snapshot){
if(snapshot.value != null){
var keys = snapshot.value.keys;
var value = snapshot.value;
// cardlist= new List();
cardlist.clear();
for (var key in keys) {
// print(key);
CardList data = CardList(
value[key]['image'],
value[key]['name'],
value[key]['designation'],
value[key]['subscribeCount'],
"",
false,
value[key]['id'],
);
cardlist.add(data);
// print(data.designation);
}
}
else {
print("No Data");
}
}
);
return
ListView.builder(
itemCount: 1,
itemBuilder: (context, i) {
return Column(
children: [
for (int i = 0; i < cardlist.length; i++)
Padding(
padding: EdgeInsets.only(
left: MediaQuery.of(context).size.width / 70,
right: MediaQuery.of(context).size.width / 30),
child: GestureDetector(
onTap: () {
dialogDisplay(context, i);
// displaysnaplist(context, i);
},
child: Container(
child: Card(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20.0),
),
elevation: 0,
child: Row(
//mainAxisAlignment: MainAxisAlignment.spaceBetween,
// crossAxisAlignment: CrossAxisAlignment.start,
children: [
Padding(
padding: EdgeInsets.only(
top: ScreenUtil().setHeight(40),
left: ScreenUtil().setHeight(40),
bottom: ScreenUtil().setHeight(40),
),
child: Container(
height: ScreenUtil().setHeight(250),
width: ScreenUtil().setHeight(250),
child: Text(""),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
image: DecorationImage(
// scale: 20,
image: NetworkImage(
cardlist[i].image,
),
fit: BoxFit.cover,
// fit: BoxFit.fitWidth
),
),
),
),
SizedBox(
width: ScreenUtil().setWidth(50),
),
Expanded(
child: Padding(
padding: EdgeInsets.only(
top: MediaQuery
.of(context)
.size
.height /
28),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
cardlist[i].name,
style: TextStyle(
decoration: TextDecoration.none,
fontFamily: 'roboto',
fontWeight: FontWeight.w600,
color: Colors.black,
),
),
SizedBox(
height:
MediaQuery
.of(context)
.size
.height /
120,
),
Text(
cardlist[i].designation,
style: TextStyle(
decoration: TextDecoration.none,
fontFamily: 'roboto',
fontSize: 10,
color: Colors.blue,
),
),
SizedBox(
height:
MediaQuery
.of(context)
.size
.height /
120,
),
Row(
children: [
Text(
cardlist[i].subscribeCount.toString(),
style: TextStyle(
decoration: TextDecoration.none,
fontFamily: 'roboto',
color: Colors.grey[700],
fontSize: 10,
),
),
SizedBox(
width: MediaQuery
.of(context)
.size
.width /
100,
),
Text(
'Subscribed',
style: TextStyle(
decoration: TextDecoration.none,
fontFamily: 'roboto',
color: Colors.grey[700],
fontSize: 10),
),
],
),
],
),
),
),
Padding(
padding: EdgeInsets.only(
top: ScreenUtil().setHeight(120),
right: ScreenUtil().setHeight(50),
),
child: Column(
children: [
Visibility(
visible: cardlist[i].show ?? true,
child: RaisedButton(
elevation: 0,
// minWidth: 100,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(
10.0),
),
color: Color(0xffF8D4D3),
child: Text(
cardlist[i].newstype,
style: TextStyle(
color: Color(0xffB53B38),
fontSize: 10),
),
onPressed: () {
dialogDisplay(context, i);
}),
),
],
),
)
],
),
),
),
),
),
],
);
});
// }
// );
}