Reputation: 198
The following exception was thrown when I tried moving from my home page to the product page. I guess the exception was thrown because of the use of the list view. Could you please help me find the correct way to use it?
It should look something like this:
But instead, it's showing me errors
======== Exception caught by rendering library ===================================================== The following assertion was thrown during performLayout(): BoxConstraints forces an infinite height.
These invalid constraints were provided to RenderDecoratedBox's layout() function by the following function, which probably computed the invalid constraints in question:
RenderConstrainedBox.performLayout (package:flutter/src/rendering/proxy_box.dart:277:14)
The offending constraints were: BoxConstraints(w=263.7, h=Infinity)
The relevant error-causing widget was:
Container file:///C:/Users/bhask/Downloads/your_store/lib/screens/product_page.dart:143:36
When the exception was thrown, this was the stack:
#0 BoxConstraints.debugAssertIsValid.<anonymous closure>.throwError (package:flutter/src/rendering/box.dart:517:9)
#1 BoxConstraints.debugAssertIsValid.<anonymous closure> (package:flutter/src/rendering/box.dart:561:21)
#2 BoxConstraints.debugAssertIsValid (package:flutter/src/rendering/box.dart:565:6)
#3 RenderObject.layout (package:flutter/src/rendering/object.dart:1679:24)
#4 RenderConstrainedBox.performLayout (package:flutter/src/rendering/proxy_box.dart:277:14)
...
The following RenderObject was being processed when the exception was fired: RenderConstrainedBox#cef26 relayoutBoundary=up10 NEEDS-LAYOUT NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE
... parentData: offset=Offset(0.0, 0.0) (can use size)
... constraints: BoxConstraints(w=263.7, 0.0<=h<=Infinity)
... size: MISSING
... additionalConstraints: BoxConstraints(w=65.0, h=Infinity)
RenderObject: RenderConstrainedBox#cef26 relayoutBoundary=up10 NEEDS-LAYOUT NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE
parentData: offset=Offset(0.0, 0.0) (can use size)
constraints: BoxConstraints(w=263.7, 0.0<=h<=Infinity)
size: MISSING
additionalConstraints: BoxConstraints(w=65.0, h=Infinity)
... child: RenderDecoratedBox#003df NEEDS-LAYOUT NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE
... parentData: <none>
... constraints: MISSING
... size: MISSING
... decoration: BoxDecoration
... color: Color(0xff000000)
... borderRadius: BorderRadius.circular(12.0)
... configuration: ImageConfiguration(bundle: PlatformAssetBundle#dc45b(), devicePixelRatio: 2.8, locale: en_US, textDirection: TextDirection.ltr, platform: android)
... child: RenderParagraph#fda35 NEEDS-LAYOUT NEEDS-PAINT
... parentData: <none>
... constraints: MISSING
... size: MISSING
... textAlign: start
... textDirection: ltr
... softWrap: wrapping at box width
... overflow: clip
... locale: en_US
... maxLines: unlimited
... text: TextSpan
... debugLabel: ((((englishLike body1 2014).merge(blackMountainView bodyText2)).copyWith).copyWith).merge(unknown)
... inherit: false
... color: Color(0xffffffff)
... family: Poppins_regular
... familyFallback: Poppins
... size: 16.0
... weight: 600
... baseline: alphabetic
... decoration: TextDecoration.none
... "Add To Cart"
====================================================================================================
======== Exception caught by rendering library =====================================================
The following assertion was thrown during performLayout():
RenderBox was not laid out: RenderConstrainedBox#cef26 relayoutBoundary=up10 NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE
'package:flutter/src/rendering/box.dart':
Failed assertion: line 1930 pos 12: 'hasSize'
Either the assertion indicates an error in the framework itself, or we should provide substantially more information in this error message to help you determine and fix the underlying cause.
In either case, please report this assertion by filing a bug on GitHub:
https://github.com/flutter/flutter/issues/new?template=2_bug.md
The relevant error-causing widget was:
Container file:///C:/Users/bhask/Downloads/your_store/lib/screens/product_page.dart:143:36
When the exception was thrown, this was the stack:
#2 RenderBox.size (package:flutter/src/rendering/box.dart:1930:12)
#3 RenderPadding.performLayout (package:flutter/src/rendering/shifted_box.dart:237:39)
#4 RenderObject.layout (package:flutter/src/rendering/object.dart:1779:7)
#5 RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:116:14)
#6 RenderObject.layout (package:flutter/src/rendering/object.dart:1779:7)
...
The following RenderObject was being processed when the exception was fired: RenderPadding#107a1 relayoutBoundary=up9 NEEDS-LAYOUT NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE
... parentData: <none> (can use size)
... constraints: BoxConstraints(w=279.7, 0.0<=h<=Infinity)
... size: MISSING
... padding: EdgeInsets(16.0, 0.0, 0.0, 0.0)
... textDirection: ltr
RenderObject: RenderPadding#107a1 relayoutBoundary=up9 NEEDS-LAYOUT NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE
parentData: <none> (can use size)
constraints: BoxConstraints(w=279.7, 0.0<=h<=Infinity)
size: MISSING
padding: EdgeInsets(16.0, 0.0, 0.0, 0.0)
textDirection: ltr
... child: RenderConstrainedBox#cef26 relayoutBoundary=up10 NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE
... parentData: offset=Offset(16.0, 0.0) (can use size)
... constraints: BoxConstraints(w=263.7, 0.0<=h<=Infinity)
... size: MISSING
... additionalConstraints: BoxConstraints(w=65.0, h=Infinity)
... child: RenderDecoratedBox#003df NEEDS-LAYOUT NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE
... parentData: <none>
... constraints: MISSING
... size: MISSING
... decoration: BoxDecoration
... color: Color(0xff000000)
... borderRadius: BorderRadius.circular(12.0)
... configuration: ImageConfiguration(bundle: PlatformAssetBundle#dc45b(), devicePixelRatio: 2.8, locale: en_US, textDirection: TextDirection.ltr, platform: android)
... child: RenderParagraph#fda35 NEEDS-LAYOUT NEEDS-PAINT
... parentData: <none>
... constraints: MISSING
... size: MISSING
... textAlign: start
... textDirection: ltr
... softWrap: wrapping at box width
... overflow: clip
... locale: en_US
... maxLines: unlimited
... text: TextSpan
... debugLabel: ((((englishLike body1 2014).merge(blackMountainView bodyText2)).copyWith).copyWith).merge(unknown)
... inherit: false
... color: Color(0xffffffff)
... family: Poppins_regular
... familyFallback: Poppins
... size: 16.0
... weight: 600
... baseline: alphabetic
... decoration: TextDecoration.none
... "Add To Cart"
====================================================================================================
Here is my code for the products page:
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:your_store/constants.dart';
import 'package:your_store/services/firebase_services.dart';
import 'package:your_store/widgets/custom_action_bar.dart';
import 'package:your_store/widgets/image_swipe.dart';
import 'package:your_store/widgets/product_size.dart';
class ProductPage extends StatefulWidget {
final String? productId;
ProductPage({this.productId});
@override
_ProductPageState createState() => _ProductPageState();
}
class _ProductPageState extends State<ProductPage> {
FirebaseServices _firebaseServices = FirebaseServices();
String? _selectedProductSize = "0";
Future _addToCart() {
return _firebaseServices.usersRef
.doc(_firebaseServices.getUserId())
.collection("Cart")
.doc(widget.productId)
.set({"size": _selectedProductSize});
}
final SnackBar _snackBar = SnackBar(content: Text("Product added to the cart."),);
@override
Widget build(BuildContext context) {
return Scaffold(
body: Stack(
children: [
FutureBuilder<DocumentSnapshot<Map<String, dynamic>>>(
future: _firebaseServices.productRef.doc(widget.productId).get(),
builder: (context, snapshot) {
if (snapshot.hasError) {
return Scaffold(
body: Center(
child: Text("Error: ${snapshot.error}"),
),
);
}
if (snapshot.connectionState == ConnectionState.done) {
//Firebase document data map
final documentData = snapshot.data!.data()!;
//List of images
List imageList = documentData["images"];
List productSize = documentData["size"];
//Set an initial size
_selectedProductSize = productSize[0];
return ListView(
padding: EdgeInsets.all(0),
children: [
ImageSwipe(
imageList: imageList,
),
Padding(
padding: const EdgeInsets.only(
top: 24.0,
left: 24.0,
right: 24.0,
bottom: 4.0,
),
child: Text(
documentData["name"] ?? "",
style: Constants.boldHeading,
),
),
Padding(
padding: const EdgeInsets.symmetric(
vertical: 4.0,
horizontal: 24.0,
),
child: Text(
documentData["price"] ?? "",
style: TextStyle(
fontSize: 18.0,
color: Theme.of(context).accentColor,
fontWeight: FontWeight.w600,
),
),
),
Padding(
padding: const EdgeInsets.symmetric(
vertical: 8.0,
horizontal: 24.0,
),
child: Text(
documentData["desc"] ?? "",
style: TextStyle(fontSize: 16.0),
),
),
Padding(
padding: const EdgeInsets.symmetric(
vertical: 24.0,
horizontal: 24.0,
),
child: Text(
"Select Size",
style: Constants.regularDarkText,
),
),
ProductSize(
productSize: productSize,
onSelected: (size){
_selectedProductSize = size;
},
),
Padding(
padding: const EdgeInsets.all(24.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Container(
width: 65.0,
height: 65.0,
decoration: BoxDecoration(
color: Color(0xFFDCDCDC),
borderRadius: BorderRadius.circular(12.0),
),
alignment: Alignment.center,
child: Image(
image: AssetImage("assets/images/tab_saved.png"),
height: 22.0,
),
),
Expanded(
child: GestureDetector(
onTap: () async {
await _addToCart();
ScaffoldMessenger.of(context).showSnackBar(_snackBar);
},
child: Container(
width: 65.0,
margin: EdgeInsets.only(
left: 16.0,
),
height: double.infinity,
decoration: BoxDecoration(
color: Colors.black,
borderRadius: BorderRadius.circular(12.0)),
child: Text(
"Add To Cart",
style: TextStyle(
color: Colors.white,
fontSize: 16.0,
fontWeight: FontWeight.w600,
),
),
),
),
),
],
),
),
],
);
}
//Loading State
return Scaffold(
body: Center(
child: CircularProgressIndicator(),
),
);
},
),
CustomActionBar(
hasBackArrow: true,
hasTitle: false,
hasBackground: false,
),
],
));
}
}
Upvotes: 1
Views: 11042
Reputation: 934
The problem is your Expanded
widget. First, you should not have an Expanded
inside of a ListView
unless the Expanded
is the child of something that has a defined height, which yours is not. Also, your ListView
is not even a child of a Widget
with a defined height. Nothing in your Widget tree knows how tall it should be. You need to set a height for all the children of your ListView
, especially the Expanded
widget. Padding
widgets do not have height, nor do Row
widgets. You need to wrap one of the immediate parents of your Expanded
in a Container
or something with a specified height, otherwise it will keep expanding forever within the ListView
and give you that infinite height
error.
Side note: you set the height of your Expanded
's child to double.infinity
, which is unecessary.
Edit:
This erroneous code:
ListView(
//...
children: [
//...
Padding(
//...
child: Row(
children: [
//...
Expanded(
child: Container(
//...
height: double.infinity,
child: Text('text'),
),
),
],
),
),
],
);
must become this:
ListView(
//...
children: [
//...
Container(
height: 100.0, //or whatever you want
width: 400.0, //or whatever you want
padding: EdgeInsets.all(24.0),
//...
child: Row(
children: [
//...
Expanded(
child: Container(
//...
child: Text('text'),
),
),
],
),
),
],
);
This is because Expanded
searches up the widget tree, looking for a parent that tells it how large it is allowed to be. You haven't provided such a parent, which results in your error message. Now, this might not fix your problem entirely because there could be other elements in your ListView
that have undefined heights. These will also cause errors because the ListView
widget bases its height on the sum of its children's heights. If ListView
doesn't know how tall each one of it's children are then it can't know how tall it should be and, again, you get that error message.
In conclusion, you need to look out for two things (not just here, but always):
Expanded
widgets have parents with defined heightsListView
widgets have defined heightsIt just so happens that you can solve both these problems by changing that Padding
widget to a sized Container
.
Upvotes: 3
Reputation: 5601
2 options
body: Stack(
fit: Stackfit.passthrough,
children: [
.... //same code
],
),
OR
return Scaffold(
body: FutureBuilder(
.... ///same code
),
bottomNavigationBar: CustomActionBar(
hasBackArrow: true,
hasTitle: false,
hasBackground: false,
),
);
Also as a sidenote this Scaffold is unnecesary
return Scaffold( /// You can remove the scaffold and keep just Center(child: CircularProgressIndicator(),)
body: Center(
child: CircularProgressIndicator(),
),
);
Stack doesn't give the children a size to perform, so ListView tries an unbounded infinite size to perform its build method
Upvotes: 2
Reputation: 156
return ListView(
shrinkWrap: true,
padding: EdgeInsets.all(0),
children: [
ImageSwipe(
imageList: imageList,
),
Padding(
padding: const EdgeInsets.only(
top: 24.0,
left: 24.0,
right: 24.0,
bottom: 4.0,
),
child: Text(
documentData["name"] ?? "",
style: Constants.boldHeading,
),
),
Padding(
padding: const EdgeInsets.symmetric(
vertical: 4.0,
horizontal: 24.0,
),
child: Text(
documentData["price"] ?? "",
style: TextStyle(
fontSize: 18.0,
color: Theme.of(context).accentColor,
fontWeight: FontWeight.w600,
),
),
),
Padding(
padding: const EdgeInsets.symmetric(
vertical: 8.0,
horizontal: 24.0,
),
child: Text(
documentData["desc"] ?? "",
style: TextStyle(fontSize: 16.0),
),
),
Padding(
padding: const EdgeInsets.symmetric(
vertical: 24.0,
horizontal: 24.0,
),
child: Text(
"Select Size",
style: Constants.regularDarkText,
),
),
ProductSize(
productSize: productSize,
onSelected: (size){
_selectedProductSize = size;
},
),
Padding(
padding: const EdgeInsets.all(24.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Container(
width: 65.0,
height: 65.0,
decoration: BoxDecoration(
color: Color(0xFFDCDCDC),
borderRadius: BorderRadius.circular(12.0),
),
alignment: Alignment.center,
child: Image(
image: AssetImage("assets/images/tab_saved.png"),
height: 22.0,
),
),
Expanded(
child: GestureDetector(
onTap: () async {
await _addToCart();
ScaffoldMessenger.of(context).showSnackBar(_snackBar);
},
child: Container(
width: 65.0,
margin: EdgeInsets.only(
left: 16.0,
),
height: double.infinity,
decoration: BoxDecoration(
color: Colors.black,
borderRadius: BorderRadius.circular(12.0)),
child: Text(
"Add To Cart",
style: TextStyle(
color: Colors.white,
fontSize: 16.0,
fontWeight: FontWeight.w600,
),
),
),
),
),
],
),
),
],
);
Upvotes: 0