Flutter - Positioned Widget in Stack causing Exception - dart

I'm getting the below exception when I try to encapsulate the PandemicCard with a Positioned widget. If I render the card lone/no Positioned widget, it works just fine.
I/flutter ( 7331): ══╡ EXCEPTION CAUGHT BY RENDERING LIBRARY ╞═════════════════════════════════════════════════════════
I/flutter ( 7331): The following assertion was thrown during performLayout():
I/flutter ( 7331): RenderStack object was given an infinite size during layout.
I/flutter ( 7331): This probably means that it is a render object that tries to be as big as possible, but it was put
I/flutter ( 7331): inside another render object that allows its children to pick their own size.
I/flutter ( 7331): The nearest ancestor providing an unbounded height constraint is:
I/flutter ( 7331): RenderFlex#2b18c relayoutBoundary=up2 NEEDS-LAYOUT NEEDS-PAINT OVERFLOWING
I/flutter ( 7331): creator: Column ← Center ← MediaQuery ← LayoutId-[<_ScaffoldSlot.body>] ← CustomMultiChildLayout ←
For this code. Anyone able to help me figure out what I'm doing wrong?
class PandemicCard extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Container(
height: 120.0,
width: 76.0,
decoration: BoxDecoration(
color: Colors.blue,
boxShadow: [
BoxShadow(
blurRadius: 5.0,
color: Colors.grey)
]),
child: Text('Hi'),
);
}
}
class PandemicCardStackState extends State<PandemicCardStack> {
// final _cards = <PandemicCard>[ PandemicCard(), PandemicCard()];
final _cards = <PandemicCard>[ PandemicCard()];
#override
Widget build( BuildContext context) {
return Stack(
// This Bombs!
children: <Widget>[ Positioned( left: 0.0, top: 0.0, child: _cards[0])]
// This works!
// children: <Widget>[ _cards[0]]
);
}
}
class PandemicCardStack extends StatefulWidget {
#override
PandemicCardStackState createState() => PandemicCardStackState();
}

Add an empty Container as a child of the stack :
#override
Widget build( BuildContext context) {
return Stack(
children: <Widget>[
Container(),
Positioned( left: 0.0, top: 0.0, child: _cards[0]),
]
);
}

Other workarounds:
(a) Wrap the Stack on a Container with a known height:
Container(
height: 50,
child: Stack(
children: [
Positioned(top: 10, left: 10, child: Text('My child'))
]),
),
(b) As suggested add empty Container() and Clip.none:
Stack(
clipBehavior: Clip.none,
children: [
Container(),
Positioned(top: 10, left: 10, child: Text('My child'))
]),

Since this is still an issue. I also came across another option.
You can wrap your stack in an IntrinsicHeight widget as well.
IntrinsicHeight(
child:
Stack(
children: [Positioned(top: 10, left: 10, child:Text('My child')
)]
),
),

Related

Flutter - How to get Container with children to take up entire screen

As per Flutter docs Containers with no children try to be as big as possible unless the incoming constraints are unbounded, in which case they try to be as small as possible. Containers with children size themselves to their children. The closest I've been to getting it to work:
return Stack(
children: <Widget>[
Container(
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height,
//width: Device.screenWidth,
//height: Device.screenHeight,
child: Column(
children: <Widget>[(view[1])],
),
),
Container(
width: MediaQuery.of(context).size.width * .50,
height: MediaQuery.of(context).size.width * .50,
child: Column(
children: <Widget>[(view[0])],
),
),
],
);
I/flutter (12292): The following message was thrown during layout:
I/flutter (12292): A RenderFlex overflowed by 81 pixels on the bottom.
I/flutter (12292): The overflowing RenderFlex has an orientation of Axis.vertical.
I/flutter (12292): The edge of the RenderFlex that is overflowing has been marked in the rendering with a yellow and
I/flutter (12292): black striped pattern. This is usually caused by the contents being too big for the RenderFlex.
Can't understand why MediaQuery or Device isn't preventing overflow? The first Container always overflows by 81 pixels on both an Android phone or tablet; no iPhone or iPad to test now. Based on what I've read from other posts overflow with yellow & black is corrected simply by wrapping in a SingleChildScrollView but when I attempt to do so I get
child: SingleChildScrollView(
child: Column(
children: <Widget>[(view[1])],
),
),
I/flutter (12292): ══╡ EXCEPTION CAUGHT BY RENDERING LIBRARY ╞═════════════════════════════════════════════════════════
I/flutter (12292): The following assertion was thrown during performLayout():
I/flutter (12292): RenderFlex children have non-zero flex but incoming height constraints are unbounded.
I/flutter (12292): When a column is in a parent that does not provide a finite height constraint, for example if it is
I/flutter (12292): in a vertical scrollable, it will try to shrink-wrap its children along the vertical axis. Setting a
I/flutter (12292): flex on a child (e.g. using Expanded) indicates that the child is to expand to fill the remaining
I/flutter (12292): space in the vertical direction.
I/flutter (12292): These two directives are mutually exclusive. If a parent is to shrink-wrap its child, the child
.
.
.
I/flutter (12292): crossAxisAlignment: center
I/flutter (12292): verticalDirection: down
I/flutter (12292): This RenderObject had the following child:
I/flutter (12292): RenderAndroidView#e356e NEEDS-LAYOUT NEEDS-PAINT
Made several other attempts with Expanded, ClipRect & other widgets based on the errors I've seen but it just made it worse where there was no image at all. Am I missing something simple or should I attempt to fix this another way?
EDIT: As per Amsakanna the latest attempt is below but still overflows by 81 pixels to produce identical error message above in the first code block.
return Stack(
children: <Widget>[
SingleChildScrollView(
child: Container(
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height,
child: Column(
children: <Widget>[view[1])],
),
),
),
I/flutter ( 1144): The following message was thrown during layout:
I/flutter ( 1144): A RenderFlex overflowed by 81 pixels on the bottom.
I/flutter ( 1144): The overflowing RenderFlex has an orientation of Axis.vertical.
I/flutter ( 1144): The edge of the RenderFlex that is overflowing has been marked in the rendering with a yellow and
I/flutter ( 1144): black striped pattern. This is usually caused by the contents being too big for the RenderFlex.
Tried to use IntrinsicHeight inside SingleChildScrollView as found here in the Expanding content to fit the viewport section but it overflows too (by 81 pixels) with similar error message.
SizedBox.expand did it for me. Here is an example of displaying an image so that the image height matches the parent and the container draws a black background in the unused space:
SizedBox.expand(
child: Container(
color: Colors.black,
child: Image (
fit: BoxFit.fitHeight,
image: AssetImage('assets/myimage.png'),
),
),
);
My approach...
return Scaffold(
appBar: AppBar(
title: Text('Title'),
),
body: Container(
color: Colors.indigo[200],
alignment: Alignment.center,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Container(
child: Image.file(_image),
),
],
),
),
);
It works for me..
return Scaffold(
appBar: AppBar(
title: Text("chatEasy"),
backgroundColor: Color.fromRGBO(102, 108, 218, 1),
),
body: Container(
child: Column(
children: <Widget>[
Expanded(
child: Container(
child: Image(
image: AssetImage("images/baseScreen.png"),
fit: BoxFit.fitHeight,
),
),
),
],
),
),
);
}
}
Wrap the Container with a SingleChildScrollView() and give the container the height and width using MediaQuery. I could achieve the results using this way. This way, the screen doesn't overflow by any pixels.
return Scaffold(
body: SingleChildScrollView(
child: Container(
height: MediaQuery.of(context).size.height,
width: MediaQuery.of(context).size.width,
child: , //child
),
),
);
You did it right by wrapping it inside a SingleChildScrollView.
The second error happens whenever you have a flex widget like 'Expanded' is placed inside a Column. If you did not place any expanded widget inside the first Column, probably it is the Camera widget doing that.
Try giving a definite size to your Camera widget by wrapping it inside a Container or SizedBox.
if you want to make a container height as much as its child take you may use this approach.
Card(
child: Flexible(
child: Container(
child: Column(
children: [
Container(
height: 30,
width: double.infinity,
color: Theme.of(context).primaryColor,
child: Align(
alignment: Alignment.centerLeft,
child: Container(
margin: EdgeInsets.only(left: 5),
child: Text('Presupuesto Por Profesional',style:
TextStyle(color: Colors.white, fontSize: 16,fontWeight:
FontWeight.bold)),
)
)
),
ProfessionalTableView(reportData.presupuestos)
],
),
),
)
),
My ProfessionalTableView is a dataTable and its length depends upon the size of the list I pass it. So the card size also depends upon the item I have in list.I wrap the parent Container with Flexible and it work.
wrap the Container with SizedBox.expand and add colors in SizedBox.

Flutter Stepper horizontal type not working

I have a problem with changing the Stepper type from vertical to horizontal.
This is my code:
body: new ListView.builder(
itemCount: data == null ? 0 : 5,
itemBuilder: (BuildContext context, int index) {
return new Card(
//child: new Text(data[index]["title"]),
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Stepper(
steps: my_steps,
type: StepperType.horizontal,
controlsBuilder: (BuildContext context,
{VoidCallback onStepContinue, VoidCallback onStepCancel}) {
return Row(
children: <Widget>[
Container(
child: null,
),
Container(
child: null,
),
],
);
},
//type: StepperType.horizontal,
),
));
},
),
After I uncomment the type I get this error:
I/flutter (10148): ══╡ EXCEPTION CAUGHT BY RENDERING LIBRARY
╞═════════════════════════════════════════════════════════ I/flutter
(10148): The following assertion was thrown during performLayout():
I/flutter (10148): RenderFlex children have non-zero flex but incoming
height constraints are unbounded. I/flutter (10148): When a column is
in a parent that does not provide a finite height constraint, for
example if it is I/flutter (10148): in a vertical scrollable, it will
try to shrink-wrap its children along the vertical axis. Setting a
I/flutter (10148): flex on a child (e.g. using Expanded) indicates
that the child is to expand to fill the remaining I/flutter (10148):
space in the vertical direction.
Your ListView has unbounded heigh so it doesn't know how much space to use for each child, which is a Stepper.
Give it some constraints, such minimum height size for each and you should be fine.
(...)
ConstrainedBox(
constraints: BoxConstraints.tightFor(height: 200.0),
child: Stepper(
steps: my_steps(),
type: StepperType.horizontal,
(...)
You can use the SizedBox() or Container() widget and set it height
SizedBox(
height: 200,
child: Card(
//child: new Text(data[index]["title"]),
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Stepper(
steps: my_steps(),
type: StepperType.horizontal,
controlsBuilder: (BuildContext context,
{VoidCallback onStepContinue, VoidCallback onStepCancel}) {
return Row(
children: <Widget>[
Container(
child: null,
),
Container(
child: null,
),
],
);
},
//type: StepperType.horizontal,
),
)),
)

Flutter - Calling persistent bottom sheet from another class

I have a persistent bottom sheet in Flutter which currently exists inside an icons onPressed(){} property.
I would like to move this persistent bottom sheet to a new class on its own but I can't seem to get it working. I am still new to flutter and can't work out how to build the structure for the persistent bottom bar.
I have currently tried the below but when I run my code, I get an exception that is thrown.
main.dart
#override
Widget build(BuildContext context) {
return Scaffold(
key: _scaffoldKey,
appBar: AppBar(
title: Text('Test App'),
actions: <Widget>[
IconButton(
icon: Icon(Icons.open_in_new),
onPressed: (){
ShowBottomSheet(context);
},
)
],
),
bottom_modal_sheet.dart
final GlobalKey<ScaffoldState> _scaffoldKey = new
GlobalKey<ScaffoldState>();
void ShowBottomSheet(BuildContext context) {
_scaffoldKey.currentState.showBottomSheet<Null>((BuildContext context)
{
return new Container(
width: double.infinity,
child: new Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Padding(
padding: EdgeInsets.only(left: 24.0, top: 16.0),
child: Text('Site Location',
style: TextStyle(fontSize: 24.0, color: Color(0xFF1181A1), fontWeight: FontWeight.bold,),
),
),
Padding(
padding: EdgeInsets.only(left: 24.0, top: 16.0),
child: Text('11 Carr Road, Three Kings, Auckland 1042',
textAlign: TextAlign.left,
style: TextStyle(fontSize: 16.0, color: Color(0xFF8596AC)),
),
),
Padding(
padding: EdgeInsets.only(left: 24.0, top: 24.0, right: 24.0, bottom: 16.0),
child: RasiedGradientButton(
child: Text('Set Location', style: TextStyle(fontSize: 24.0, fontWeight: FontWeight.bold, color: Colors.white)),
gradient: LinearGradient(
colors: <Color>[Color(0xFFFCCF58), Color(0xFFFEAA00)]
),
onPressed: (){
print('button clicked');
},
)
),
],
));
});
}
I am getting the error:
I/flutter (19024): ══╡ EXCEPTION CAUGHT BY GESTURE
╞═══════════════════════════════════════════════════════════════════
I/flutter (19024): The following NoSuchMethodError was thrown while
handling a gesture:
I/flutter (19024): The method 'showBottomSheet' was called on null.
I/flutter (19024): Receiver: null
I/flutter (19024): Tried calling: showBottomSheet<Null>(Closure:
(BuildContext) => Container)
I/flutter (19024):
You just need call showBottomSheet in your screen widget that you want show the bottom sheet and return the widget of your custom bottom sheet. The snippet show how to do this. Read the source comments.
// our Screen widget class
class MyScreen extends StatefulWidget {
#override
_MyScreenScreenState createState() => _MyScreenScreenState();
}
class _MyScreenState extends State<MyScreenScreen> {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Test App'),
actions: <Widget>[
IconButton( icon: Icon(Icons.open_in_new),
onPressed: (){
_showMyBottomSheet();
},
)
],
),
);
}
void _showMyBottomSheet(){
// the context of the bottomSheet will be this widget
//the context here is where you want to showthe bottom sheet
showBottomSheet(context: context,
builder: (BuildContext context){
return MyBottomSheetLayout(); // returns your BottomSheet widget
}
);
}
}
//your bottom sheet widget class
//you can put your things here, like buttons, callbacks and layout
class MyBottomSheetLayout extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Container(); // return your bottomSheetLayout
}
}

Nested ListViews in flutter gives horizontal viewport error

Im trying to make a gallery UI like Netflix with horizontal ListViews inside a Vertical ListView, but I keep getting viewport errors and cant get around it.
Full Code.
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Live Tree',
home: Scaffold(
appBar: AppBar(
title: Text("Netflux"),
),
body: HomePage(),
),
);
}
}
class HomePage extends StatefulWidget {
HomePage({Key key}) : super(key: key);
#override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
#override
Widget build(BuildContext context) {
Row getMediaForCategory(CategoryModel category) {
List<Column> mediaItems = [];
for (Media media in category.media) {
mediaItems.add(
Column(
mainAxisSize: MainAxisSize.min,
children: [
media.image,
Container(
color: Colors.black,
padding: EdgeInsets.only(top: 8, bottom: 8),
child: Text(media.title),
)
],
),
);
}
return Row(mainAxisSize: MainAxisSize.min, children: mediaItems);
}
List<ListView> getCategoryRows(List<CategoryModel> categoryModels) {
List<ListView> categoryRows = [];
for (CategoryModel category in categoryModels) {
categoryRows.add(
ListView(
scrollDirection: Axis.horizontal,
children: [getMediaForCategory(category)]),
);
}
return categoryRows;
}
Widget gallerySection = ListView(
children: getCategoryRows(mockCategoryDataSet),
);
return Scaffold(
body: gallerySection,
);
}
}
If I change the nested ListViews to rows there are rendered but not scrollable.
With the nested ListViews I get the following Error:
I/flutter ( 9048): ══╡ EXCEPTION CAUGHT BY RENDERING LIBRARY ╞═════════════════════════════════════════════════════════
I/flutter ( 9048): The following assertion was thrown during performResize():
I/flutter ( 9048): Horizontal viewport was given unbounded height.
I/flutter ( 9048): Viewports expand in the cross axis to fill their container and constrain their children to match
I/flutter ( 9048): their extent in the cross axis. In this case, a horizontal viewport was given an unlimited amount of
I/flutter ( 9048): vertical space in which to expand.
The problem is that your horizontal list view doesn't have a height so you're better off using a SingleChildScrollView and a Row so the height can be implied by the content:
List<Widget> getCategoryRows(List<CategoryModel> categoryModels) {
List<Widget> categoryRows = [];
for (CategoryModel category in categoryModels) {
categoryRows.add(
SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Row(
children: [getMediaForCategory(category)],
),
),
);
}
return categoryRows;
}

Flutter - How to make PageView & ListView?

I'm trying to make a Carousel using PageView, PageController and ListView from this Horizontally scrollable cards with Snap effect in flutter. But it throwed this exception...
══╡ EXCEPTION CAUGHT BY RENDERING LIBRARY ╞═════════════════════════════════════════════════════════
I/flutter (17678): The following assertion was thrown during performResize():
I/flutter (17678): Horizontal viewport was given unbounded height.
I/flutter (17678): Viewports expand in the cross axis to fill their container and constrain their children to match
I/flutter (17678): their extent in the cross axis. In this case, a horizontal viewport was given an unlimited amount of
I/flutter (17678): vertical space in which to expand.
Can someone help me to fix it?
I want to add this Carousel inside of Stack-filled with background image, transform class, and fade transition.
#override
void initState() {
super.initState();
controller = PageController(
initialPage: 0,
keepPage: true,
);
#override
Widget build(BuildContext context) {
return AnimatedBuilder(
builder: (BuildContext context, Widget child) {
return Scaffold(
//BODY
body: ListView(children: <Widget>[
new Stack(
children: <Widget>[
new AspectRatio(...),
new Transform(...),
//THIS IS
new ListView.builder(
itemCount: 3,
scrollDirection: Axis.horizontal,
padding: EdgeInsets.symmetric(vertical: 16.0),
itemBuilder: (BuildContext context, int index) {
if (index % 3 == 0) {
return _buildCarousel(context, index ~/ 3);
} else {
return Divider();
}
},
),
}
}
}
Widget _buildCarousel(BuildContext context, int carouselIndex) {
return Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Text('Carousel $carouselIndex'),
SizedBox(
// you may want to use an aspect ratio here for tablet support
height: 200.0,
child: PageView.builder(
// store this controller in a State to save the carousel scroll position
controller: PageController(viewportFraction: 0.8),
itemBuilder: (BuildContext context, int itemIndex) {
return _buildCarouselItem(context, carouselIndex, itemIndex);
},
),
)
],
);
Widget _buildCarouselItem(
BuildContext context, int carouselIndex, int itemIndex) {
return Padding(
padding: EdgeInsets.symmetric(horizontal: 4.0),
child: Container(
decoration: BoxDecoration(
color: Colors.grey,
borderRadius: BorderRadius.all(Radius.circular(4.0)),
),
),
);
This is the full code https://pastebin.com/xXRkaWuR
As you might have guessed from the error, basically it means since you haven't specified a finite height,ListView is getting infinite height.
Try using shrinkWrap: true inside your ListView.builder and ListView.
Or alternatively you can also try wrapping your ListViews in a Container or SizedBox of finite height.
Example-
Container(
height: 200.0,
child: ListView(
/*Remaining Code*/
),
)
You can try doing the same with ListView.builder

Resources