A RenderViewport expected a child of type RenderSliver but received a child of type RenderPositionedBox - flutter

encountered this error after changing some labels, I don't even remember changing the widgets:
I know that this is a sliver and box issue but I tried changing and removing widgets to fix this problem to no avail
return Scaffold(
backgroundColor: Colors.grey[200],
floatingActionButton: Column(
mainAxisAlignment: MainAxisAlignment.end,
children: [
FloatingActionButton(
onPressed: () {
//PATIENT.
if (currTab == 0) {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => const AddPatient(),
),
);
} else {
//SHIPMENT.
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => const AddShipment(),
),
);
}
},
heroTag: null,
child: Icon(currTab == 0
? Icons.person_add
: Icons.add_shopping_cart_rounded),
),
const SizedBox(
height: 10,
),
currTab == 0 ? _getFAB() : const SizedBox(),
// FloatingActionButton(
// onPressed: () {},
// heroTag: null,
// child: const Icon(Icons.sort_rounded),
// ),
],
),
resizeToAvoidBottomInset: true,
body: DefaultTabController(
length: 2,
child: NestedScrollView(
body: TabBarView(
controller: _tabController,
physics: const NeverScrollableScrollPhysics(),
children: [
StreamBuilder<List<Patient>>(
stream: readPatients(orderTypePatients),
builder: (context, snapshot) {
if (snapshot.hasData) {
countPatients = snapshot.data!.length;
} else {
countPatients = 0;
}
return CustomScrollView(
slivers: [
if (snapshot.hasData)
SliverList(
delegate: SliverChildBuilderDelegate(
(BuildContext context, int index) {
if (snapshot.hasData) {
final patient = snapshot.data;
return makeCardPatient(patient![index]);
} else if (!snapshot.hasData) {
return const Center(
child: CircularProgressIndicator(
color: Colors.green),
);
} else if (snapshot.hasError) {
return const SliverToBoxAdapter(
child: Center(child: Text('has err')));
} else {
return const Center(
child: CircularProgressIndicator(
color: Colors.green),
);
}
},
childCount: snapshot.data?.length,
),
)
else if (snapshot.hasError)
Center(
child: Text(
snapshot.error.toString(),
style: const TextStyle(fontWeight: FontWeight.bold),
),
)
else
const SliverToBoxAdapter(
child: Padding(
padding: EdgeInsets.all(10.0),
child: Center(
child: CircularProgressIndicator(
color: Colors.green,
),
),
),
),
SliverToBoxAdapter(
child: Padding(
padding: const EdgeInsets.all(12.0),
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Text(
'Total:\n$totalSumPatients',
textAlign: TextAlign.center,
style: const TextStyle(
color: Colors.black,
fontWeight: FontWeight.bold,
fontSize: 21,
),
),
],
),
),
),
],
);
},
),
StreamBuilder<List<Shipment>>(
stream: readShipments(orderTypeShipments),
builder: (context, snapshot) {
if (snapshot.hasData) {
countShipments = snapshot.data!.length;
} else {
countShipments = 0;
}
return CustomScrollView(
slivers: [
if (snapshot.hasData)
SliverList(
delegate: SliverChildBuilderDelegate(
(BuildContext context, int index) {
if (snapshot.hasData) {
final shipment = snapshot.data;
return makeCardShipment(shipment![index]);
} else if (!snapshot.hasData) {
return const Center(
child: CircularProgressIndicator(
color: Colors.green),
);
} else if (snapshot.hasError) {
return const SliverToBoxAdapter(
child: Center(child: Text('has err')));
} else {
return const Center(
child: CircularProgressIndicator(
color: Colors.green),
);
}
},
childCount: snapshot.data?.length,
),
)
else if (snapshot.hasError)
SliverToBoxAdapter(
child: Center(
child: Text(
snapshot.error.toString(),
style: const TextStyle(fontWeight: FontWeight.bold),
),
))
else
const SliverToBoxAdapter(
child: Padding(
padding: EdgeInsets.all(10.0),
child: Center(
child: CircularProgressIndicator(
color: Colors.green,
),
),
),
),
SliverToBoxAdapter(
child: Padding(
padding: const EdgeInsets.all(12.0),
child: Center(
child: Text(
'Total:\n$totalSumShipment',
textAlign: TextAlign.center,
style: const TextStyle(
color: Colors.black,
fontWeight: FontWeight.w900,
fontSize: 21,
),
),
),
),
),
],
);
},
),
],
),
headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) {
return [
SliverAppBar(
stretch: true,
bottom: TabBar(
controller: _tabController,
indicatorSize: TabBarIndicatorSize.tab,
indicatorColor: Colors.green,
indicatorWeight: 5,
labelColor: Colors.green,
labelStyle: const TextStyle(
color: Colors.black,
fontWeight: FontWeight.bold,
),
unselectedLabelColor: Colors.grey,
overlayColor:
MaterialStateProperty.all<Color>(Colors.grey[300]!),
onTap: (value) {
totalSumShipment = 0;
totalSumPatients = 0;
searchController.clear();
FocusManager.instance.primaryFocus?.unfocus();
currTab = value;
setState(() {});
},
tabs: [
Tab(
icon: Stack(
children: [
Icon(
Icons.supervised_user_circle_rounded,
color: currTab == 0 ? Colors.green : Colors.grey,
size: 36,
),
countPatients == 0
? const SizedBox(
height: 1,
)
: Positioned(
right: 0,
child: Container(
padding: const EdgeInsets.all(1),
decoration: BoxDecoration(
color: Colors.red,
borderRadius: BorderRadius.circular(7),
),
constraints: const BoxConstraints(
minWidth: 15,
minHeight: 15,
maxHeight: 15,
maxWidth: 15,
),
child: Text(
countPatients.toInt().toString(),
style: const TextStyle(
color: Colors.white,
fontSize: 10,
),
textAlign: TextAlign.center,
),
),
),
],
),
text: 'Patients',
),
Tab(
icon: Stack(
children: [
Icon(
Icons.shopping_bag_rounded,
color: currTab == 1 ? Colors.green : Colors.grey,
size: 36,
),
countShipments == 0
? const SizedBox(
height: 1,
)
: Positioned(
right: 0,
child: Container(
padding: const EdgeInsets.all(1),
decoration: BoxDecoration(
color: Colors.red,
borderRadius: BorderRadius.circular(7),
),
constraints: const BoxConstraints(
minWidth: 15,
minHeight: 15,
maxHeight: 15,
maxWidth: 15,
),
child: Text(
countShipments.toInt().toString(),
style: const TextStyle(
color: Colors.white,
fontSize: 10,
),
textAlign: TextAlign.center,
),
),
),
],
),
text: 'Orders',
),
],
),
pinned: true,
snap: false,
floating: true,
elevation: 10,
expandedHeight: 300.0,
stretchTriggerOffset: 150.0,
backgroundColor: Colors.grey.shade200,
flexibleSpace: FlexibleSpaceBar(
stretchModes: const [
StretchMode.zoomBackground,
StretchMode.fadeTitle,
StretchMode.blurBackground,
],
titlePadding: const EdgeInsetsDirectional.all(0),
background: SafeArea(
child: Stack(
alignment: AlignmentDirectional.topCenter,
fit: StackFit.loose,
children: [
Positioned(
top: 5,
right: 5,
child: IconButton(
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => const SettingsPage(),
),
);
},
icon: const Icon(Icons.settings_rounded)),
),
Positioned(
top: 10,
right: 1,
left: 1,
child: Padding(
padding: const EdgeInsets.all(50.0),
child: GestureDetector(
onTap: () {
log(countShipments.toString());
setState(() {});
},
child: Image.asset(
'assets/images/my_Logo.png',
fit: BoxFit.fitWidth,
),
),
),
),
Positioned(
top: 120,
left: 10,
right: 10,
child: Padding(
padding: const EdgeInsets.all(30.0),
child: searchField(),
),
),
],
),
),
centerTitle: true,
collapseMode: CollapseMode.pin,
),
)
];
},
),
),
);
↑ is the scaffold
Card makeCardPatient(Patient patient) {
totalSumPatients = totalSumPatients + patient.balance;
return Card(
elevation: 8.0,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(25.0),
),
margin: const EdgeInsets.symmetric(
horizontal: 10.0,
vertical: 6.0,
),
child: Container(
decoration: BoxDecoration(
color: const Color.fromARGB(228, 64, 96, 72),
borderRadius: BorderRadius.circular(25),
),
child: makeListTilePatient(patient),
),
);
}
↑ is the card wiget that is called in the streambuilder to create the Card widget
ListTile makeListTilePatient(Patient patient) {
return ListTile(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(25),
),
contentPadding: const EdgeInsets.symmetric(
horizontal: 20.0,
vertical: 10.0,
),
leading: Container(
padding: const EdgeInsets.only(right: 12.0),
decoration: const BoxDecoration(
border: Border(
right: BorderSide(
width: 1.0,
color: Colors.white24,
),
),
),
child: CircleAvatar(
radius: 25,
backgroundColor: patient.balance == 0 ? Colors.blue : Colors.red,
child: Text(
patient.balance.toStringAsFixed(2).toUpperCase(),
style: const TextStyle(
fontWeight: FontWeight.bold,
fontSize: 18,
),
),
),
),
title: Text(
patient.name,
style: const TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold,
),
),
subtitle: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Expanded(
flex: 1,
child: Text(
DateFormat('yyyy/MM/dd').format(patient.lastvisit) == '1986/09/25'
? ' '
: timeAgo(patient.lastvisit),
style: const TextStyle(
fontWeight: FontWeight.bold,
color: Colors.black,
),
),
),
Expanded(
flex: 1,
child: Padding(
padding: const EdgeInsets.only(left: 10.0),
child: Text(
DateFormat('yyyy/MM/dd').format(patient.appointment) ==
'1986/09/25'
? ' '
: timeFromNow(patient.appointment),
style: const TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold,
),
),
),
)
],
),
trailing: const Icon(
Icons.keyboard_arrow_right,
color: Colors.white,
size: 30.0,
),
onTap: () {
totalSumPatients = 0;
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => Details(
patient: patient,
),
),
);
setState(() {});
},
);
}
↑ is the Tile widget to detail whats in the card.
I know that there is something that I'm not seeing but tried searching and editing for a long while and I didnt find what I'm missing.
I'm new to SO can you please help me?
I tried wrapping some widgets with Slivertoboxadapter but didnt work.
extra functions used ,I dont think they are related to the problem but here they are:
Stream<List<Shipment>> readShipments(String orderTypeShipments) {
return FirebaseFirestore.instance
.collection('shipments')
.orderBy(
orderTypeShipments,
descending: sortOrder,
)
.snapshots()
.map((snapshot) => snapshot.docs
.map((doc) => Shipment.fromJson(doc.data()))
.where(
(element) =>
element.userId.toUpperCase() ==
Helper.currUserID.toUpperCase() &&
element.type.toUpperCase().contains(
searchController.text.toUpperCase(),
),
)
.toList());
}
Future<int> getPatientCount() async {
var x = FirebaseFirestore.instance
.collection('patients')
.orderBy(
orderTypePatients.toUpperCase(),
descending: sortOrder,
)
.snapshots()
.map((snapshot) => snapshot.docs
.map((doc) => Patient.fromJson(doc.data()))
.where((element) =>
element.user == Helper.currUserID &&
(element.name
.toUpperCase()
.contains(searchController.text.toUpperCase())))
.toList());
setState(() {});
return x.length;
}

As suggested by #Yeasin Sheikh I overlooked that line, silly me.
thanks yeasin.
I just had to wrap the Center widget with a SliverToBoxAdapter in the snapshot.error:
SliverToBoxAdapter(child:Center(...

Related

The method 'OutlineButton' isn't defined

I know the OutlineButton is Old version
and New version is OutlinedButton.
When I turn into new one then show error in the another padding ,color, shape borderSide.
Please see my screenshot
My project: environment:
sdk: ">=2.11.0 <3.0.0"
module:
androidX: true
dependencies:
flutter:
sdk: flutter
flutter_localizations:
sdk: flutter
And My Insttaled : [√] Flutter Channel stable, 3.0.5,
import 'package:cached_network_image/cached_network_image.dart';
import 'package:carousel_slider/carousel_slider.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:mvc_pattern/mvc_pattern.dart';
import '../../generated/l10n.dart';
import '../controllers/product_controller.dart';
import '../elements/AddToCartAlertDialog.dart';
import '../elements/CircularLoadingWidget.dart';
import '../elements/OptionItemWidget.dart';
import '../elements/ReviewsListWidget.dart';
import '../elements/ShoppingCartFloatButtonWidget.dart';
import '../helpers/helper.dart';
import '../models/media.dart';
import '../models/route_argument.dart';
import '../repository/user_repository.dart';
// ignore: must_be_immutable
class ProductWidget extends StatefulWidget {
RouteArgument routeArgument;
ProductWidget({Key key, this.routeArgument}) : super(key: key);
#override
_ProductWidgetState createState() {
return _ProductWidgetState();
}
}
class _ProductWidgetState extends StateMVC<ProductWidget> {
ProductController _con;
_ProductWidgetState() : super(ProductController()) {
_con = controller;
}
#override
void initState() {
_con.listenForProduct(productId: widget.routeArgument.id);
_con.listenForCart();
_con.listenForFavorite(productId: widget.routeArgument.id);
super.initState();
}
#override
Widget build(BuildContext context) {
return Scaffold(
key: _con.scaffoldKey,
body: _con.product == null || _con.product?.image == null || _con.product?.images == null
? CircularLoadingWidget(height: 500)
: RefreshIndicator(
onRefresh: _con.refreshProduct,
child: Stack(
fit: StackFit.expand,
children: <Widget>[
Container(
margin: EdgeInsets.only(bottom: 125),
padding: EdgeInsets.only(bottom: 15),
child: CustomScrollView(
primary: true,
shrinkWrap: false,
slivers: <Widget>[
SliverAppBar(
backgroundColor: Theme.of(context).accentColor.withOpacity(0.9),
expandedHeight: 275,
elevation: 0,
iconTheme: IconThemeData(color: Theme.of(context).primaryColor),
flexibleSpace: FlexibleSpaceBar(
collapseMode: CollapseMode.parallax,
background: Stack(
alignment: AlignmentDirectional.bottomCenter,
children: <Widget>[
CarouselSlider(
options: CarouselOptions(
autoPlay: true,
autoPlayInterval: Duration(seconds: 7),
height: 300,
enableInfiniteScroll: false,
viewportFraction: 1.0,
onPageChanged: (index, reason) {
setState(() {
_con.current = index;
});
},
),
items: _con.product.images.map((Media image) {
return Builder(
builder: (BuildContext context) {
return CachedNetworkImage(
height: 300,
width: double.infinity,
fit: BoxFit.cover,
imageUrl: image.url,
placeholder: (context, url) => Image.asset(
'assets/img/loading.gif',
fit: BoxFit.cover,
width: double.infinity,
height: 300,
),
errorWidget: (context, url, error) => Icon(Icons.error_outline),
);
},
);
}).toList(),
),
Visibility(
visible: _con.product.images.length > 1,
child: Container(
//margin: EdgeInsets.symmetric(vertical: 22, horizontal: 42),
child: Row(
mainAxisSize: MainAxisSize.min,
children: _con.product.images.map((Media image) {
return Container(
width: 20.0,
height: 5.0,
margin: EdgeInsets.symmetric(vertical: 20.0, horizontal: 2.0),
decoration: BoxDecoration(
borderRadius: BorderRadius.all(
Radius.circular(10),
),
color: _con.current == _con.product.images.indexOf(image)
? Theme.of(context).accentColor
: Theme.of(context).primaryColor.withOpacity(0.4)),
);
}).toList(),
),
),
),
],
),
),
),
SliverToBoxAdapter(
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 15),
child: Wrap(
runSpacing: 8,
children: [
Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Expanded(
flex: 3,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
_con.product?.name ?? '',
overflow: TextOverflow.ellipsis,
maxLines: 2,
style: Theme.of(context).textTheme.headline3,
),
Text(
_con.product?.market?.name ?? '',
overflow: TextOverflow.ellipsis,
maxLines: 2,
style: Theme.of(context).textTheme.bodyText2,
),
],
),
),
Expanded(
flex: 1,
child: Column(
crossAxisAlignment: CrossAxisAlignment.end,
children: <Widget>[
Helper.getPrice(
_con.product.price,
context,
style: Theme.of(context).textTheme.headline2,
),
_con.product.discountPrice > 0
? Helper.getPrice(_con.product.discountPrice, context,
style: Theme.of(context).textTheme.bodyText2.merge(TextStyle(decoration: TextDecoration.lineThrough)))
: SizedBox(height: 0),
],
),
),
],
),
Row(
children: <Widget>[
Container(
padding: EdgeInsets.symmetric(horizontal: 12, vertical: 3),
decoration: BoxDecoration(
color: Helper.canDelivery(_con.product.market) && _con.product.deliverable ? Colors.green : Colors.orange,
borderRadius: BorderRadius.circular(24)),
child: Helper.canDelivery(_con.product.market) && _con.product.deliverable
? Text(
S.of(context).deliverable,
style: Theme.of(context).textTheme.caption.merge(TextStyle(color: Theme.of(context).primaryColor)),
)
: Text(
S.of(context).not_deliverable,
style: Theme.of(context).textTheme.caption.merge(TextStyle(color: Theme.of(context).primaryColor)),
),
),
Expanded(child: SizedBox(height: 0)),
Visibility(
visible: _con.product.capacity != null && _con.product.capacity != "null",
child: Container(
padding: EdgeInsets.symmetric(horizontal: 12, vertical: 3),
decoration: BoxDecoration(color: Theme.of(context).focusColor, borderRadius: BorderRadius.circular(24)),
child: Text(
_con.product.capacity + " " + _con.product.unit,
style: Theme.of(context).textTheme.caption.merge(TextStyle(color: Theme.of(context).primaryColor)),
)),
),
SizedBox(width: 5),
Visibility(
visible: _con.product.packageItemsCount != null && _con.product.packageItemsCount != "null",
child: Container(
padding: EdgeInsets.symmetric(horizontal: 12, vertical: 3),
decoration: BoxDecoration(color: Theme.of(context).focusColor, borderRadius: BorderRadius.circular(24)),
child: Text(
_con.product.packageItemsCount + " " + S.of(context).items,
style: Theme.of(context).textTheme.caption.merge(TextStyle(color: Theme.of(context).primaryColor)),
)),
),
],
),
Divider(height: 20),
Text(Helper.skipHtml(_con.product.description)),
if (_con.product.optionGroups.isNotEmpty)
ListTile(
dense: true,
contentPadding: EdgeInsets.symmetric(vertical: 10),
leading: Icon(
Icons.add_circle_outline,
color: Theme.of(context).hintColor,
),
title: Text(
S.of(context).options,
style: Theme.of(context).textTheme.subtitle1,
),
subtitle: Text(
S.of(context).select_options_to_add_them_on_the_product,
style: Theme.of(context).textTheme.caption,
),
),
ListView.separated(
padding: EdgeInsets.all(0),
itemBuilder: (context, optionGroupIndex) {
var optionGroup = _con.product.optionGroups.elementAt(optionGroupIndex);
print("SIZE:::${_con.product.options.where((option) => option.optionGroupId == optionGroup.id).length}");
return Wrap(
children: <Widget>[
ListTile(
dense: true,
contentPadding: EdgeInsets.symmetric(vertical: 0),
leading: Icon(
Icons.add_circle_outline,
color: Theme.of(context).hintColor,
),
title: Text(
optionGroup.name,
style: Theme.of(context).textTheme.subtitle1,
),
),
ListView.separated(
padding: EdgeInsets.all(0),
itemBuilder: (context, optionIndex) {
return OptionItemWidget(
option: _con.product.options.where((option) => option.optionGroupId == optionGroup.id).elementAt(optionIndex),
onChanged: _con.calculateTotal,
);
},
separatorBuilder: (context, index) {
return SizedBox(height: 20);
},
itemCount: _con.product.options.where((option) => option.optionGroupId == optionGroup.id).length,
primary: false,
shrinkWrap: true,
),
],
);
},
separatorBuilder: (context, index) {
return SizedBox(height: 20);
},
itemCount: _con.product.optionGroups.length,
primary: false,
shrinkWrap: true,
),
/*ListTile(
dense: true,
contentPadding: EdgeInsets.symmetric(vertical: 10),
leading: Icon(
Icons.recent_actors_outlined,
color: Theme.of(context).hintColor,
),
title: Text(
S.of(context).reviews,
style: Theme.of(context).textTheme.subtitle1,
),
),
ReviewsListWidget(
reviewsList: _con.product.productReviews,
),*/
],
),
),
),
],
),
),
Positioned(
top: 32,
right: 20,
child: _con.loadCart
? SizedBox(
width: 60,
height: 60,
child: RefreshProgressIndicator(),
)
: ShoppingCartFloatButtonWidget(
iconColor: Theme.of(context).primaryColor,
labelColor: Theme.of(context).hintColor,
routeArgument: RouteArgument(param: '/Product', id: _con.product.id),
),
),
Positioned(
bottom: 0,
child: Container(
height: 150,
padding: EdgeInsets.symmetric(horizontal: 20, vertical: 8),
decoration: BoxDecoration(
color: Theme.of(context).primaryColor,
borderRadius: BorderRadius.only(topRight: Radius.circular(20), topLeft: Radius.circular(20)),
boxShadow: [BoxShadow(color: Theme.of(context).focusColor.withOpacity(0.15), offset: Offset(0, -2), blurRadius: 5.0)]),
child: SizedBox(
width: MediaQuery.of(context).size.width - 40,
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisSize: MainAxisSize.max,
children: <Widget>[
Row(
children: <Widget>[
Expanded(
child: Text(
S.of(context).quantity,
style: Theme.of(context).textTheme.subtitle1,
),
),
Row(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
IconButton(
onPressed: () {
_con.decrementQuantity();
},
iconSize: 30,
padding: EdgeInsets.symmetric(horizontal: 5, vertical: 10),
icon: Icon(Icons.remove_circle_outline),
color: Theme.of(context).hintColor,
),
Text(_con.quantity.toString(), style: Theme.of(context).textTheme.subtitle1),
IconButton(
onPressed: () {
_con.incrementQuantity();
},
iconSize: 30,
padding: EdgeInsets.symmetric(horizontal: 5, vertical: 10),
icon: Icon(Icons.add_circle_outline),
color: Theme.of(context).hintColor,
)
],
),
],
),
SizedBox(height: 10),
Row(
children: <Widget>[
Expanded(
child: _con.favorite?.id != null
? OutlineButton(
onPressed: () {
_con.removeFromFavorite(_con.favorite);
},
padding: EdgeInsets.symmetric(vertical: 14),
color: Theme.of(context).primaryColor,
shape: StadiumBorder(),
borderSide: BorderSide(color: Theme.of(context).accentColor),
child: Icon(
Icons.favorite,
color: Theme.of(context).accentColor,
))
: MaterialButton(
elevation: 0,
onPressed: () {
if (currentUser.value.apiToken == null) {
Navigator.of(context).pushNamed("/Login");
} else {
_con.addToFavorite(_con.product);
}
},
padding: EdgeInsets.symmetric(vertical: 14),
color: Theme.of(context).accentColor,
shape: StadiumBorder(),
child: Icon(
Icons.favorite_outline,
color: Theme.of(context).primaryColor,
)),
),
SizedBox(width: 10),
Stack(
fit: StackFit.loose,
alignment: AlignmentDirectional.centerEnd,
children: <Widget>[
SizedBox(
width: MediaQuery.of(context).size.width - 110,
child: MaterialButton(
elevation: 0,
onPressed: () {
if (currentUser.value.apiToken == null) {
Navigator.of(context).pushNamed("/Login");
} else {
if (_con.isSameMarkets(_con.product)) {
_con.addToCart(_con.product);
} else {
showDialog(
context: context,
builder: (BuildContext context) {
// return object of type Dialog
return AddToCartAlertDialogWidget(
oldProduct: _con.carts.elementAt(0)?.product,
newProduct: _con.product,
onPressed: (product, {reset: true}) {
return _con.addToCart(_con.product, reset: true);
});
},
);
}
}
},
padding: EdgeInsets.symmetric(vertical: 14),
color: Theme.of(context).accentColor,
shape: StadiumBorder(),
child: Container(
width: double.infinity,
padding: const EdgeInsets.symmetric(horizontal: 20),
child: Text(
S.of(context).add_to_cart,
textAlign: TextAlign.start,
style: TextStyle(color: Theme.of(context).primaryColor),
),
),
),
),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 20),
child: Helper.getPrice(
_con.total,
context,
style: Theme.of(context).textTheme.headline4.merge(TextStyle(color: Theme.of(context).primaryColor)),
),
)
],
),
],
),
SizedBox(height: 10),
],
),
),
),
)
],
),
),
);
}
}
The outlinedButton doesnt have the properties like color borderside etc you can give the color and border using style property like.
style: ButtonStyle(
backgroundColor: MaterialStateProperty.all<Color>(Colors.green),
),
Add the following style to your outlinedButton it will work for you.
style: ButtonStyle(
padding: MaterialStateProperty.all(
EdgeInsets.symmetric(vertical: 14),
),
backgroundColor:
MaterialStateProperty.all(Theme.of(context).primaryColor),
shape: MaterialStateProperty.all(
StadiumBorder(),
),
),

I cant see my data Firebase DB on Flutter

I can see my data on Flutter Databese, but it disappears on the loading screen. It appears and disappears at first, what is the reason, how can I solve this problem ?
When I press the product group, the data appears at first, but then it disappears.
import 'package:flutter/material.dart';
import 'package:warehouse_management/models/product.dart';
import 'package:warehouse_management/screens/new_product_page.dart';
import 'package:warehouse_management/screens/search_product_in_group.dart';
import 'package:warehouse_management/utils/color_palette.dart';
import 'package:warehouse_management/widgets/product_card.dart';
class ProductGroupPage extends StatelessWidget {
final String? name;
ProductGroupPage({Key? key, this.name}) : super(key: key);
final FirebaseFirestore _firestore = FirebaseFirestore.instance;
#override
Widget build(BuildContext context) {
return Scaffold(
floatingActionButton: Padding(
padding: const EdgeInsets.only(
bottom: 10,
right: 10,
),
child: FloatingActionButton(
onPressed: () {
Navigator.of(context).push(
MaterialPageRoute(
builder: (context) {
return NewProductPage(
group: name,
);
},
),
);
},
splashColor: ColorPalette.bondyBlue,
backgroundColor: ColorPalette.pacificBlue,
child: const Icon(
Icons.add,
color: ColorPalette.white,
),
),
),
body: Container(
color: ColorPalette.pacificBlue,
child: SafeArea(
child: Container(
color: ColorPalette.aquaHaze,
height: double.infinity,
width: double.infinity,
child: Column(
children: [
Container(
padding: const EdgeInsets.only(
top: 10,
left: 10,
right: 15,
),
width: double.infinity,
height: 90,
decoration: const BoxDecoration(
color: ColorPalette.pacificBlue,
borderRadius: BorderRadius.only(
bottomLeft: Radius.circular(16),
bottomRight: Radius.circular(16),
),
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Row(
children: [
IconButton(
icon: const Icon(
Icons.chevron_left_rounded,
size: 35,
),
onPressed: () {
Navigator.of(context).pop();
},
),
Text(
name!.length > 14
? '${name!.substring(0, 12)}..'
: name!,
style: const TextStyle(
fontFamily: "Nunito",
fontSize: 28,
color: ColorPalette.timberGreen,
),
),
],
),
Row(
children: [
IconButton(
splashColor: ColorPalette.timberGreen,
icon: const Icon(
Icons.search,
color: ColorPalette.timberGreen,
),
onPressed: () {
Navigator.of(context).push(
MaterialPageRoute(
builder: (context) =>
SearchProductInGroupPage(
name: name,
),
),
);
},
),
IconButton(
icon: const Icon(
Icons.delete,
color: ColorPalette.timberGreen,
),
onPressed: () {
//TODO
},
),
],
)
],
),
),
Expanded(
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 20),
child: SizedBox(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: const [
SizedBox(
height: 20,
),
],
),
const Text(
"Ürünler",
style: TextStyle(
color: ColorPalette.timberGreen,
fontSize: 20,
fontFamily: "Nunito",
),
),
const SizedBox(height: 20),
Expanded(
child: StreamBuilder(
stream: _firestore
.collection("products")
.where("group", isEqualTo: name)
.orderBy('name')
.snapshots(),
builder: (
BuildContext context,
AsyncSnapshot<
QuerySnapshot<Map<String, dynamic>>>
snapshot,
) {
if (!snapshot.hasData) {
return const Center(
child: SizedBox(
height: 40,
width: 40,
child: CircularProgressIndicator(
color: Colors.black,
),
),
);
}
return ListView.builder(
itemCount: snapshot.data!.docs.length,
itemBuilder:
(BuildContext context, int index) {
return ProductCard(
product: Product.fromMap(
snapshot.data!.docs[index].data(),
),
docID: snapshot.data!.docs[index].id,
);
},
);
},
),
),
],
),
),
),
),
],
),
),
),
),
);
}
}
You can also find the fields I created for Firebase in the appendix.
When I click on the first field on the previous page, my data appears and then disappears.
Then, after 1 second, my data disappears, it appears on firebase, but not on the screen.
<meta-data
android:name="io.flutter.embedding.android.SplashScreenDrawable"
android:resource="#drawable/launch_background"
/>
The solution is to remove the above code.

How to align rows at bottom of the screen along with other containers at top

I am trying to achieve a UI in which there are 2 buttons in the center and then afterwards there are 2 rows at the bottom of the screen fixed respective to screen sizes I will stay at its place, but I'm unable to do it in my case I'm using Column and all the other containers and rows are in it.
Desired Result on emulator is fine
What I am getting in real device
Here is the code.
class IntroPage extends StatelessWidget {
const IntroPage({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: const Color(0xFFF29F76),
body: SingleChildScrollView(
child: Column(
children: <Widget>[
Stack(
children: <Widget>[
Image.asset(
"assets/intropage.png",
fit: BoxFit.fill,
),
Padding(
padding: const EdgeInsets.only(
top: 550,
),
child: Center(
child: GestureDetector(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => const SignUpPage()));
},
child: Container(
width: 180,
height: 60,
decoration: BoxDecoration(
color: Colors.white,
border: Border.all(
color: Colors.white,
),
borderRadius:
const BorderRadius.all(Radius.circular(40))),
child: const Center(
child: Text(
"Sign Up",
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
color: Colors.black),
),
),
),
),
),
),
Padding(
padding: const EdgeInsets.only(
top: 650,
),
child: Center(
child: GestureDetector(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => const SignInPage()));
},
child: Container(
width: 180,
height: 60,
decoration: BoxDecoration(
color: Colors.white,
border: Border.all(
color: Colors.white,
),
borderRadius:
const BorderRadius.all(Radius.circular(40))),
child: const Center(
child: Text(
"Sign In",
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
color: Color(0xFFFE6B01)),
),
),
),
),
),
),
Padding(
padding: const EdgeInsets.only(
top: 750,
),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Container(
height: 2,
width: 150,
color: Colors.white,
),
const Text(
" Please Read ",
style: TextStyle(color: Colors.white),
),
Container(
height: 2,
width: 150,
color: Colors.white,
),
],
),
),
Padding(
padding: const EdgeInsets.only(
top: 760,
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Padding(
padding: const EdgeInsets.only(left: 20, top: 6),
child: GestureDetector(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) =>
TermsandConditions()));
},
child: const Text(
"Terms & Conditions",
style: TextStyle(
color: Colors.white,
decoration: TextDecoration.underline),
),
),
),
Padding(
padding: const EdgeInsets.only(right: 20, top: 6),
child: GestureDetector(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => PrivacyPolicy()));
},
child: const Text(
"Privacy Policy",
style: TextStyle(
color: Colors.white,
decoration: TextDecoration.underline),
),
),
),
],
),
),
],
)
],
),
),
);
}
}
Use this method its will do the job. Background image will appear and you can align your widgets using the Alignment property
class IntroPage extends StatelessWidget {
const IntroPage({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return Container(
decoration: const BoxDecoration(
image: DecorationImage(
fit: BoxFit.fill,
image: AssetImage(
'assets/intropage.png',
),
)),
child: Scaffold(
backgroundColor: Colors.transparent,
body: Stack(
children: <Widget>[
Align(
alignment: Alignment.center,
child: Padding(
padding: const EdgeInsets.only(top: 250.0),
child: Center(
child: GestureDetector(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => const SignUpPage()));
},
child: Container(
width: 180,
height: 60,
decoration: BoxDecoration(
color: Colors.white,
border: Border.all(
color: Colors.white,
),
borderRadius:
const BorderRadius.all(Radius.circular(40))),
child: const Center(
child: Text(
"Sign Up",
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
color: Colors.black),
),
),
),
),
),
),
),
Align(
alignment: Alignment.center,
child: Padding(
padding: const EdgeInsets.only(top: 500.0),
child: Center(
child: GestureDetector(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => const SignInPage()));
},
child: Container(
width: 180,
height: 60,
decoration: BoxDecoration(
color: Colors.white,
border: Border.all(
color: Colors.white,
),
borderRadius:
const BorderRadius.all(Radius.circular(40))),
child: const Center(
child: Text(
"Sign In",
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
color: Color(0xFFFE6B01)),
),
),
),
),
),
),
),
Align(
alignment: Alignment.bottomCenter,
child: Padding(
padding: const EdgeInsets.only(bottom: 20),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Container(
height: 2,
width: 150,
color: Colors.white,
),
const Text(
" Please Read ",
style: TextStyle(color: Colors.white),
),
Container(
height: 2,
width: 150,
color: Colors.white,
),
],
),
),
),
Align(
alignment: Alignment.bottomCenter,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Padding(
padding: const EdgeInsets.only(left: 20, top: 6),
child: GestureDetector(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => TermsandConditions()));
},
child: const Text(
"Terms & Conditions",
style: TextStyle(
color: Colors.white,
decoration: TextDecoration.underline),
),
),
),
Padding(
padding: const EdgeInsets.only(right: 20, top: 6),
child: GestureDetector(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => PrivacyPolicy()));
},
child: const Text(
"Privacy Policy",
style: TextStyle(
color: Colors.white,
decoration: TextDecoration.underline),
),
),
),
],
),
),
],
)),
);
}
}
Try to wrap your widgets inside
Positioned(
Align(
alignment: Alignment.bottomCenter,
child: _your_widget_here()
It's not recommanded to use fix value for the layout.
Stack here it's not necessary.
A simple Spacer Widget can the work. But there are multiple way to do it.
import 'package:flutter/material.dart';
class IntroPage extends StatelessWidget {
const IntroPage({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: const Color(0xFFF29F76),
body: SingleChildScrollView(
child: Column(
children: <Widget>[
Image.asset(
"assets/intropage.png",
fit: BoxFit.fitWidth,
),
const Spacer(),
Padding(
padding: const EdgeInsets.all(8.0),
child: Center(
child: GestureDetector(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => const SignUpPage()));
},
child: Container(
width: 180,
height: 60,
decoration: BoxDecoration(
color: Colors.white,
border: Border.all(
color: Colors.white,
),
borderRadius:
const BorderRadius.all(Radius.circular(40))),
child: const Center(
child: Text(
"Sign Up",
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
color: Colors.black),
),
),
),
),
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: Center(
child: GestureDetector(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => const SignInPage()));
},
child: Container(
width: 180,
height: 60,
decoration: BoxDecoration(
color: Colors.white,
border: Border.all(
color: Colors.white,
),
borderRadius:
const BorderRadius.all(Radius.circular(40))),
child: const Center(
child: Text(
"Sign In",
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
color: Color(0xFFFE6B01)),
),
),
),
),
),
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Container(
height: 2,
width: 150,
color: Colors.white,
),
const Text(
" Please Read ",
style: TextStyle(color: Colors.white),
),
Container(
height: 2,
width: 150,
color: Colors.white,
),
],
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Padding(
padding: const EdgeInsets.only(left: 20, top: 6),
child: GestureDetector(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) =>
TermsandConditions()));
},
child: const Text(
"Terms & Conditions",
style: TextStyle(
color: Colors.white,
decoration: TextDecoration.underline),
),
),
),
Padding(
padding: const EdgeInsets.only(right: 20, top: 6),
child: GestureDetector(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => PrivacyPolicy()));
},
child: const Text(
"Privacy Policy",
style: TextStyle(
color: Colors.white,
decoration: TextDecoration.underline),
),
),
),
],
),
],
),
),
);
}
}
If you can use standard buttons, use them. I used ElevatedButton with custom styles, so please check it.
In general it is a bad idea to add accumulated top padding to each element. Screens sizes are different and your layout will be failed on another screen size.
Please see my example of how to do this better.
Also I added other small improvements, maybe you will be interested in.
class IntroPage extends StatelessWidget {
const IntroPage({Key? key}) : super(key: key);
Widget _createButton({
required VoidCallback onPressed,
required Widget child,
required Color textColor,
}) {
return ElevatedButton(
onPressed: onPressed,
child: child,
style: ElevatedButton.styleFrom(
elevation: 0.0,
primary: Colors.white,
onPrimary: textColor,
textStyle: TextStyle(
fontSize: 20.0,
fontWeight: FontWeight.bold,
),
padding: EdgeInsets.all(8.0),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(40),
),
fixedSize: Size(180.0, 60.0),
),
);
}
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: const Color(0xFFF29F76),
body: SafeArea(
child: Column(
children: <Widget>[
Expanded(
child: Stack(
children: <Widget>[
Align(
alignment: Alignment.topCenter,
child: SizedBox(
height: 400.0, //your image height
child: Image.network(
"https://images.ctfassets.net/hrltx12pl8hq/61DiwECVps74bWazF88Cy9/2cc9411d050b8ca50530cf97b3e51c96/Image_Cover.jpg?fit=fill&w=480&h=270",
fit: BoxFit.cover,
),
),
),
Align(
alignment: Alignment.bottomCenter,
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
_createButton(
child: Text("Sign Up"),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
//your page
builder: (context) => Container(),
),
);
},
textColor: Colors.black,
),
SizedBox(height: 32.0),
_createButton(
child: Text("Sign In"),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
//your page
builder: (context) => Container(),
),
);
},
textColor: Color(0xFFFE6B01),
),
SizedBox(height: 32.0),
],
),
),
],
),
),
_BottomSection(),
],
),
),
);
}
}
class _BottomSection extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: const <Widget>[
Expanded(
child: Divider(
height: 2,
thickness: 2,
color: Colors.white,
),
),
SizedBox(width: 10),
Text(
"Please Read",
style: TextStyle(color: Colors.white),
),
SizedBox(width: 10),
Expanded(
child: Divider(
height: 2,
thickness: 2,
color: Colors.white,
),
),
],
),
Padding(
padding: const EdgeInsets.only(
top: 6.0,
right: 20.0,
left: 20.0,
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
GestureDetector(
onTap: () {
Navigator.push(context,
MaterialPageRoute(builder: (context) => Container()));
},
child: const Text(
"Terms & Conditions",
style: TextStyle(
color: Colors.white,
decoration: TextDecoration.underline),
),
),
GestureDetector(
onTap: () {
Navigator.push(context,
MaterialPageRoute(builder: (context) => Container()));
},
child: const Text(
"Privacy Policy",
style: TextStyle(
color: Colors.white,
decoration: TextDecoration.underline),
),
),
],
),
),
],
);
}
}

Refresh listview based on button click

I have a list of categories and products. I want that when I click on a category:
The selected category should change color to orange.
The products listview should be refreshed with the selected category's products.
I tried to add setState and try to change both color and listview but that did not work. Any ideas what I need to rectify?
Future fetchProducts() async {
return await Provider.of<Products>(context, listen: false)
.fetchAndSetProducts('title', false);
}
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.grey[100],
appBar: AppBar(
backgroundColor: Colors.grey[100],
elevation: 0,
brightness: Brightness.light,
leading: Icon(null),
actions: <Widget>[
IconButton(
onPressed: () {},
icon: Icon(
Icons.shopping_basket,
color: Colors.grey[800],
),
)
],
),
body: SafeArea(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Padding(
padding: EdgeInsets.symmetric(horizontal: 10.0),
child: FutureBuilder(
future: _screenFuture,
// ignore: missing_return
builder: (context, snap) {
if (snap.error != null &&
!snap.error
.toString()
.contains('NoSuchMethodError')) {
return Center(child: Text('Something went wrong!'));
} else if (snap.hasData) {
var categoriesData = Provider.of<Categories>(context);
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
FadeAnimation(
1,
Text(
'Food Delivery',
style: TextStyle(
color: Colors.grey[80],
fontWeight: FontWeight.bold,
fontSize: 30),
)),
SizedBox(
height: 20,
),
Container(
height: 50,
child: ListView.builder(
scrollDirection: Axis.horizontal,
itemCount: categoriesData.items.length,
itemBuilder: (ctx, i) => FadeAnimation(
i.toDouble(),
makeCategory(
isActive: i.toDouble() == 0
? true
: false,
title: categoriesData.items
.toList()[i]
.title)))),
SizedBox(
height: 10,
),
],
);
} else if (snap.connectionState ==
ConnectionState.waiting) {
//return Container();
return Center(child: Spinner());
}
})),
Padding(
padding: EdgeInsets.symmetric(horizontal: 20.0),
child: FutureBuilder(
future: _productScreenFuture,
// ignore: missing_return
builder: (context, snap) {
if (snap.error != null &&
!snap.error
.toString()
.contains('NoSuchMethodError')) {
return Center(child: Text('Something went wrong!'));
} else if (snap.hasData) {
productsData = Provider.of<Products>(context);
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: <Widget>[
FadeAnimation(
1,
Text(
'Food Delivery',
style: TextStyle(
color: Colors.grey[80],
fontWeight: FontWeight.bold,
fontSize: 30),
)),
SizedBox(
height: 20,
),
SizedBox(
height: 300,
child: ListView.builder(
shrinkWrap: true,
scrollDirection: Axis.horizontal,
itemCount: productsData.items.length,
itemBuilder: (ctx, i) => FadeAnimation(
1.4,
makeItem(
image: 'assets/images/one.jpg',
title: productsData.items[i].title,
price:
productsData.items[i].price)))),
SizedBox(
height: 10,
),
],
);
} else if (snap.connectionState ==
ConnectionState.waiting) {
//return Container();
return Center(child: Spinner());
}
})),
SizedBox(
height: 30,
)
],
),
),
);
}
Widget makeCategory({isActive, title}) {
return AspectRatio(
aspectRatio: isActive ? 3 : 2.5 / 1,
child: GestureDetector(
onTap: () {
print(title + " clicked");
setState(() {
isActive = true;
productsData = Provider.of<Products>(context, listen: false)
.findBycategoryName(title);
print(productsData.first.title); // << data is available
});
},
child: Container(
margin: EdgeInsets.only(right: 10),
decoration: BoxDecoration(
color: isActive ? Colors.yellow[700] : Colors.white,
borderRadius: BorderRadius.circular(50),
),
child: Align(
child: Text(
title,
style: TextStyle(
color: isActive ? Colors.white : Colors.grey[500],
fontSize: 18,
fontWeight: isActive ? FontWeight.bold : FontWeight.w100),
),
),
),
));
}
Widget makeItem({image, String title, double price}) {
return AspectRatio(
aspectRatio: 1 / 1.5,
child: GestureDetector(
child: Container(
margin: EdgeInsets.only(right: 20),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(20),
image: DecorationImage(
image: AssetImage(image),
fit: BoxFit.cover,
)),
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(20),
gradient: LinearGradient(begin: Alignment.bottomCenter, stops: [
.2,
.9
], colors: [
Colors.black.withOpacity(.9),
Colors.black.withOpacity(.3),
])),
child: //Expanded(
Padding(
padding: EdgeInsets.all(20.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Align(
alignment: Alignment.topRight,
child: Icon(
Icons.favorite,
color: Colors.white,
),
),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Text(
"\Tsh. $price",
style: TextStyle(
color: Colors.white,
fontSize: 20,
fontWeight: FontWeight.bold),
),
SizedBox(
height: 10,
),
Text(
title,
style: TextStyle(color: Colors.white, fontSize: 20),
)
],
)
],
),
),
),
),
),
);
}
}
Actually When you call setState() your isActive is again changed to false because of this code:
makeCategory(
isActive: i.toDouble() == 0
? true
: false,
TRY THIS CODE:
bool currentCategory = 0;
Future fetchProducts() async {
return await Provider.of<Products>(context, listen: false)
.fetchAndSetProducts('title', false);
}
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.grey[100],
appBar: AppBar(
backgroundColor: Colors.grey[100],
elevation: 0,
brightness: Brightness.light,
leading: Icon(null),
actions: <Widget>[
IconButton(
onPressed: () {},
icon: Icon(
Icons.shopping_basket,
color: Colors.grey[800],
),
)
],
),
body: SafeArea(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Padding(
padding: EdgeInsets.symmetric(horizontal: 10.0),
child: FutureBuilder(
future: _screenFuture,
// ignore: missing_return
builder: (context, snap) {
if (snap.error != null &&
!snap.error
.toString()
.contains('NoSuchMethodError')) {
return Center(child: Text('Something went wrong!'));
} else if (snap.hasData) {
var categoriesData = Provider.of<Categories>(context);
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
FadeAnimation(
1,
Text(
'Food Delivery',
style: TextStyle(
color: Colors.grey[80],
fontWeight: FontWeight.bold,
fontSize: 30),
)),
SizedBox(
height: 20,
),
Container(
height: 50,
child: ListView.builder(
scrollDirection: Axis.horizontal,
itemCount: categoriesData.items.length,
itemBuilder: (ctx, i) => FadeAnimation(
i.toDouble(),
makeCategory(
isActive: i == currentCategory
? true
: false,
position: i,
title: categoriesData.items
.toList()[i]
.title)))),
SizedBox(
height: 10,
),
],
);
} else if (snap.connectionState ==
ConnectionState.waiting) {
//return Container();
return Center(child: Spinner());
}
})),
Padding(
padding: EdgeInsets.symmetric(horizontal: 20.0),
child: FutureBuilder(
future: _productScreenFuture,
// ignore: missing_return
builder: (context, snap) {
if (snap.error != null &&
!snap.error
.toString()
.contains('NoSuchMethodError')) {
return Center(child: Text('Something went wrong!'));
} else if (snap.hasData) {
productsData = Provider.of<Products>(context);
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: <Widget>[
FadeAnimation(
1,
Text(
'Food Delivery',
style: TextStyle(
color: Colors.grey[80],
fontWeight: FontWeight.bold,
fontSize: 30),
)),
SizedBox(
height: 20,
),
SizedBox(
height: 300,
child: ListView.builder(
shrinkWrap: true,
scrollDirection: Axis.horizontal,
itemCount: productsData.items.length,
itemBuilder: (ctx, i) => FadeAnimation(
1.4,
makeItem(
image: 'assets/images/one.jpg',
title: productsData.items[i].title,
price:
productsData.items[i].price)))),
SizedBox(
height: 10,
),
],
);
} else if (snap.connectionState ==
ConnectionState.waiting) {
//return Container();
return Center(child: Spinner());
}
})),
SizedBox(
height: 30,
)
],
),
),
);
}
Widget makeCategory({isActive, title, position}) {
return AspectRatio(
aspectRatio: isActive ? 3 : 2.5 / 1,
child: GestureDetector(
onTap: () {
print(title + " clicked");
setState(() {
currentCategory = position;
productsData = Provider.of<Products>(context, listen: false)
.findBycategoryName(title);
print(productsData.first.title); // << data is available
});
},
child: Container(
margin: EdgeInsets.only(right: 10),
decoration: BoxDecoration(
color: isActive ? Colors.yellow[700] : Colors.white,
borderRadius: BorderRadius.circular(50),
),
child: Align(
child: Text(
title,
style: TextStyle(
color: isActive ? Colors.white : Colors.grey[500],
fontSize: 18,
fontWeight: isActive ? FontWeight.bold : FontWeight.w100),
),
),
),
));
}
Widget makeItem({image, String title, double price}) {
return AspectRatio(
aspectRatio: 1 / 1.5,
child: GestureDetector(
child: Container(
margin: EdgeInsets.only(right: 20),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(20),
image: DecorationImage(
image: AssetImage(image),
fit: BoxFit.cover,
)),
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(20),
gradient: LinearGradient(begin: Alignment.bottomCenter, stops: [
.2,
.9
], colors: [
Colors.black.withOpacity(.9),
Colors.black.withOpacity(.3),
])),
child: //Expanded(
Padding(
padding: EdgeInsets.all(20.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Align(
alignment: Alignment.topRight,
child: Icon(
Icons.favorite,
color: Colors.white,
),
),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Text(
"\Tsh. $price",
style: TextStyle(
color: Colors.white,
fontSize: 20,
fontWeight: FontWeight.bold),
),
SizedBox(
height: 10,
),
Text(
title,
style: TextStyle(color: Colors.white, fontSize: 20),
)
],
)
],
),
),
),
),
),
);
}
}
the isActive is not a variable and when you change it in setState nothing happens. try using a int? index variable for saving your selected category index

Duplicate GlobalKey detected in Widget Tree or Multiple Widgets used the same GlobalKey

I've tried to create form to input something from textfield to database using rest service, it worked just fine from the first try, but it got error the next time I tried, the error said there was something wrong with the GlobalkKey, so it's maybe around here.
class _DeliveryRecieverState extends State<DeliveryReciever> {
List datas;
File imagePath;
bool validasi = false;
String namaPenerima;
final _keyFormReceiver = GlobalKey<FormState>();
#override
Widget build(BuildContext context) {
datas = this.datas;
print(datas);
return DefaultTabController(
length: 1,
child: Scaffold(
backgroundColor: Colors.white,
appBar: AppBar(
bottom: TabBar(
tabs: <Widget>[
Tab(
icon: Icon(Icons.local_shipping),
text: "Bukti Delivery",
),
],
),
elevation: 0.1,
// backgroundColor: Colors.cyan[800],
flexibleSpace: Container(
decoration: BoxDecoration(
gradient: LinearGradient(
colors: [Color(0xFF17ead9), Color(0xFF6078ea)]),
),
),
title: Text(
"Delivery",
style: TextStyle(
fontFamily: "Popins-Bold",
fontSize: ScreenUtil.getInstance().setSp(46),
letterSpacing: .6,
fontWeight: FontWeight.bold,
),
),
actions: <Widget>[
],
),
body: TabBarView(
children: <Widget>[
SingleChildScrollView(
child: Padding(
padding: EdgeInsets.only(
left: 15.0, right: 15.0, top: 15.0, bottom: 15.0),
child: Column(
children: <Widget>[
Container(
width: double.infinity,
height: ScreenUtil.getInstance().setHeight(470),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(8.0),
boxShadow: [
BoxShadow(
color: Colors.black12,
offset: Offset(0.0, 15.0),
blurRadius: 15.0),
BoxShadow(
color: Colors.black12,
offset: Offset(0.0, -10.0),
blurRadius: 10.0)
]),
child: Padding(
padding: EdgeInsets.only(
left: 16.0, right: 16.0, top: 16.0),
child: Form(
key: _keyFormReceiver,
autovalidate: validasi,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
"Nama Penerima",
style: TextStyle(
fontSize:
ScreenUtil.getInstance().setSp(30),
fontFamily: "Poppins-Bold",
letterSpacing: .6),
),
SizedBox(
height:
ScreenUtil.getInstance().setHeight(30),
),
TextFormField(
validator: validasiReceivername,
onSaved: (String nama) {
namaPenerima = nama;
},
decoration: InputDecoration(
hintText: "Nama Penerima",
hintStyle: TextStyle(
color: Colors.grey,
fontSize: 12.0)),
),
SizedBox(
height:
ScreenUtil.getInstance().setHeight(50),
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Padding(
padding: const EdgeInsets.all(10.0),
child: RaisedButton(
elevation: 7.0,
color: Colors.green,
padding: EdgeInsets.all(20.0),
child: Text("LANJUT"),
textColor: Colors.white,
shape: RoundedRectangleBorder(
borderRadius:
BorderRadius.circular(10)),
onPressed: () {
parseData();
},
),
),
],
),
],
),
)),
),
],
),
),
),
],
),
bottomNavigationBar: Container(
height: 55.0,
child: BottomAppBar(
child: Container(
decoration: BoxDecoration(
gradient: LinearGradient(
colors: [Color(0xFF17ead9), Color(0xFF6078ea)]),
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
IconButton(
icon: Icon(Icons.home, color: Colors.white),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => halamanUtama()),
);
},
),
IconButton(
icon: Icon(Icons.nature_people, color: Colors.white),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => UpcomingDelivery()),
);
},
),
IconButton(
icon: Icon(Icons.local_shipping, color: Colors.white),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => ListDelivery()),
);
},
),
],
),
),
),
),
));
}
String validasiReceivername(String value) {
if (value.length == 0) {
//Toast.show("Password more than 4 ", context,duration: Toast.LENGTH_SHORT, gravity: Toast.CENTER);
return "Nama penerima tidak boleh kosong.";
} else {
return null;
}
}
void parseData() async {
if (_keyFormReceiver.currentState.validate()) {
_keyFormReceiver.currentState.save();
_keyFormReceiver.currentState.reset();
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => CustomerSignatureProof(
created_name: widget.created_name,
wmsorders_id: widget.wmsorders_id,
imagePath: widget.imagePath,
imageName: widget.imageName,
receiverName: namaPenerima,
upcoming_id: widget.upcoming_id,
upcoming_sku: widget.upcoming_sku,
upcoming_sak: widget.upcoming_sak,
upcoming_qty: widget.upcoming_qty,
upcoming_shipstatid: widget.upcoming_shipstatid,
upcoming_picname: widget.upcoming_picname,
upcoming_pictelp: widget.upcoming_pictelp,
upcoming_ordermultipleid: widget.upcoming_ordermultipleid,
upcoming_orderdetid: widget.upcoming_orderdetid,
upcoming_coordinatorid: widget.upcoming_coordinatorid,
upcoming_shipmentid: widget.upcoming_shipmentid)));
}
}
}
Here is the error in terminal,
Have anybody face the same probles as me, please give your guidance..