how to distribute space between multiple items - dart

I am trying to add an image that covers the top 20% of the screen and the other 80% should be a grid of cards. The image needs to be in the body and not on the Appbar. I made the grid of cards, and then I tried to put the image and the grid in a column. The implementation is the following.
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
primary: true,
appBar: AppBar(
elevation: 4.0,
backgroundColor: Color(0xfff8f8f8),
title: Center(child: titleLogo,),
),
//------------ PROBLEM BELOW ----------------
body: new Column(
children: <Widget>[
titleLogo, //Image object
TheGridView().build() //Returns a GridView object
],
),
),
);
}
I am getting the following error
I/flutter (21751): The following assertion was thrown during performResize():
I/flutter (21751): Vertical viewport was given unbounded height.
I/flutter (21751): Viewports expand in the scrolling direction to fill their container.In this case, a vertical
I/flutter (21751): viewport was given an unlimited amount of vertical space in which to expand. This situation
I/flutter (21751): typically happens when a scrollable widget is nested inside another scrollable widget.
I/flutter (21751): If this widget is always nested in a scrollable widget there is no need to use a viewport because
I/flutter (21751): there will always be enough vertical space for the children. In this case, consider using a Column
I/flutter (21751): instead. Otherwise, consider using the "shrinkWrap" property (or a ShrinkWrappingViewport) to size
I/flutter (21751): the height of the viewport to the sum of the heights of its children.
Any suggestion is highly appreciated. Thank you in advance.

for distributing space between multiple items you should use the Expanded widget like this:
return new Column(
children: <Widget>[
new Expanded(
flex: 2,
child: new Container(
color: Colors.red,
),
),
new Expanded(
flex: 8,
child: new Container(//use your Gridview instead
color: Colors.green,
)
)
],
);

Related

PageView.builder giving Horizontal viewport was given unbounded height error

I'm very new to flutter and I'm trying to learn how to create views. I tried to create a separate file of the view, or widget if that's what it's called in flutter, and just call it from the main.dart.
I have a separate widget containing this code
class PageEntryWidgetMain extends StatefulWidget {
final PageViewEntryMain pageViewEntryMain;
const PageEntryWidgetMain({Key key, this.pageViewEntryMain})
: super(key: key);
#override
State<StatefulWidget> createState() {
return _PageEntryWidgetMainState();
}
}
class _PageEntryWidgetMainState extends State<PageEntryWidgetMain> {
#override
Widget build(BuildContext context) {
return Container(
child: Row(
children: <Widget>[
Text(widget.pageViewEntryMain.title)
],
),
);
}
}
and I'm trying to show it by using a view pager with the following code
return Scaffold(
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
PageView.builder(
itemBuilder: (context, position) {
PageEntryWidgetMain(
pageViewEntryMain: pages[position],
);
},
itemCount: pages.length,
scrollDirection: Axis.horizontal,
)
],
),
),
);
but it gives me the following errors
Horizontal viewport was given unbounded height.
Viewports expand in the cross axis to fill their container and constrain their children to match their extent in the cross axis. In this case, a horizontal viewport was given an unlimited amount of vertical space in which to expand.
I'm a little confused at what it's actually complaining of. I am able to display just one view, by replacing the PageView.builder with this code
PageEntryWidgetMain(pageViewEntryMain: pages[0])
So I believe that the separate widget, in itself, does not have a problem. It's probably about how I am trying to use the ViewPager that's giving me errors.
I have been searching for PageView implementations but I have not seen one that actually has a separate view to just call for displaying. I need to learn it this way so I would be able to separate the views instead of just writing it all in one file.
PageView cannot be the direct child of Column. Change your column to add an Expanded between the two, as below:
Column(
children: <Widget>[
Expanded(
child: PageView.builder(),
),
]
)
To explain what's going on here, Column has an unbounded horizontal width, ie it'll keep expanding horizontally to take as much space as it's child needs. PageView (and any other horizontally scrolling widget) requires horizontal constraints for the scroll logic to work.
Expanded restricts the horizontal size of the PageView by taking up as much space as possible, which should solve the issue.
You can use any Widget that has a fixed height and width to wrap the PageView.
For example, I use Container():
Column(
children: <Widget>[
Container(
width: double.infinity,
height: 100.0,
child: PageView.builder(),
),
]
)

Placing a widget in a column gives RenderIndexedStack object was given an infinite size during layout

I am placing the following in column like this
Widget _getDropDownCombo()
{
Widget combo = new DropdownButton(
value: _currentItem,
items:_dropDownMenuItems,
onChanged: _changedDropDownItem
);
return Flexible(child:combo);
}
and _getDropDownCombo is being called from a row somewhere like this
child: new Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
_getDropDownCombo(),
getIcon(),
],)
This gives me the error
flutter: ══╡ EXCEPTION CAUGHT BY RENDERING LIBRARY ╞═════════════════════════════════════════════════════════
flutter: The following assertion was thrown during performLayout():
flutter: RenderIndexedStack object was given an infinite size during layout.
flutter: This probably means that it is a render object that tries to be as big as possible, but it was put
flutter: inside another render object that allows its children to pick their own size.
flutter: The nearest ancestor providing an unbounded width constraint is:
flutter: RenderFlex#dfcbf relayoutBoundary=up17 NEEDS-LAYOUT NEEDS-PAINT
Why am I getting this error with DropDownButton ? Any suggestions ?
Their might be problem because of the items inside your DropdownButton.
I've tried using this in items and it works just fine:
items: ['Foo', 'Bar'].map((String value) {
return new DropdownMenuItem(
value: value,
child: new Text(value),
);
}).toList(),

AnimatedCrossFade with ListView got unbounded height error

here is the code. what I want is showing progress when requesting result, and display the result as a list when requesting completed.
I choose the AnimatedCrossFade cause it had convinient transition animation;
Widget SearchResultPage() {
return AnimatedCrossFade(
firstChild: Center(
child: CircularProgressIndicator(),
),
secondChild: ListView.builder(
itemCount: _searchResult.length,
itemBuilder: (BuildContext context, int index) {
return SearchListItem(_searchResult[index]);
}),
crossFadeState: _searchResult.isEmpty
? CrossFadeState.showFirst
: CrossFadeState.showSecond,
duration: Duration(milliseconds: 500));
}
Widget SearchListItem(BookFuzzySearchDetail detail) {
return Container(
decoration:
BoxDecoration(border: Border(bottom: BorderSide(color: Colors.grey))),
child: ListTile(
contentPadding: EdgeInsets.symmetric(vertical: 5.0, horizontal: 4.0),
leading: Image.network(
detail.cover,
width: 50.0,
height: 50.0,
),
title: Text(
detail.title,
),
),
);
}
and I got the error:
I/flutter ( 6281): ══╡ EXCEPTION CAUGHT BY RENDERING LIBRARY ╞═════════════════════════════════════════════════════════
I/flutter ( 6281): The following assertion was thrown during performResize():
I/flutter ( 6281): Vertical viewport was given unbounded height.
I/flutter ( 6281): Viewports expand in the scrolling direction to fill their container.In this case, a vertical
I/flutter ( 6281): viewport was given an unlimited amount of vertical space in which to expand. This situation
I/flutter ( 6281): typically happens when a scrollable widget is nested inside another scrollable widget.
I/flutter ( 6281): If this widget is always nested in a scrollable widget there is no need to use a viewport because
I/flutter ( 6281): there will always be enough vertical space for the children. In this case, consider using a Column
I/flutter ( 6281): instead. Otherwise, consider using the "shrinkWrap" property (or a ShrinkWrappingViewport) to size
I/flutter ( 6281): the height of the viewport to the sum of the heights of its children.
New to flutter and stucked here for a few days, appreciate for any advice please.
Try adding the property shrinkWrap to your ListView.builder
ListView.builder(
shrinkWrap: true,
itemCount: _searchResult.length,
itemBuilder: (BuildContext context, int index) {
return SearchListItem(_searchResult[index]);
}),
AnimatedCrossFade not only animates the opacity change of both widgets, but also the size transition; since the size of the list is unknown at build time (I mean build lifecycle method, not building the project) without shrinkWrap: true it throws an exception.
As #nickolay-savchenko pointed out in the comment to the accepted answer, shrinkWrap: true may cause significant performance issues and is definitely an unnecessary overkill for this case.
I'd advise using AnimatedSwitcher instead of AnimatedCrossFade, which will only do the opacity change (default behaviour).
Arguably, you don't need to animate the size change between a large possibly screen-overflowing list and "empty search results" widget.
Here is how I used it in one of my projects to animate transition between the list and "loading" widget:
AnimatedSwitcher(
duration: const Duration(milliseconds: 500),
child: items.isEmpty
? const LoadingWidget()
: ListView.builder(
itemCount: items.length,
itemBuilder: (context, index) => ...
),
),

Position FloatingActionButton on the left side

How do I position a FloatingActionButton on the left side inside a Scaffold?
Currently the only available options are centerFloat, centerDocked, endFloat and endDocked.
Maybe Material Design does not intend to position the FAB at startFloat or startDocked.
That would be fine if RTL changed endFloat and endDocked to appear on the left side, but that is not the case.
In April 2020, the available options have been expanded and startFloat as well as startDocked are included options now.
Here is the full list of available options (see the FloatingActionButtonLocation documentation):
centerDocked
centerFloat
centerTop
endDocked
endFloat
endTop
miniCenterDocked
miniCenterFloat
miniCenterTop
miniEndDocked
miniEndFloat
miniEndTop
miniStartDocked
miniStartFloat
miniStartTop
startDocked
startFloat
startTop
You can even easily define your own locations using StandardFabLocation.
As of 2020, you can use the following:
floatingActionButtonLocation: FloatingActionButtonLocation.startFloat
A parameter that can be passed to the Scaffold Widget from material.dart
Source: PR 51465
There is also another solution to this problem. Fab button by default is always at the bottom end of the screen. So if we wrap our Scaffoldwith a Directionality and set its text direction to TextDirection.rtl, then the button goes left. but since now the body itself is mirrored, we can wrap the body with another Directionality and set its text direction to TextDirection.ltr
#override
Widget build(BuildContext context) {
return
Directionality(
textDirection: TextDirection.rtl,
child:Scaffold(
appBar: AppBar(
title: const Text('Something),
),
body: Directionality(
textDirection: TextDirection.ltr,
child: Center(child: const Text('Press the button below!'))),
floatingActionButton: FloatingActionButton(
onPressed: () {
},
child: Icon(Icons.navigation),
backgroundColor: Colors.green,
),
)
);
}

How to pass multiple widgets as children in Flutter? [duplicate]

This question already has answers here:
Can't add a ListView in Flutter
(3 answers)
Closed 4 years ago.
I recently started learning Flutter and have been going through the documentation. I am working on this small app, where the screen has a button on the top of the screen and a list below it.
Whenever I pass RaisedButton with a ListView widget into another ListView or Column Widget, its throwing error.
I/flutter ( 4734): ══╡ EXCEPTION CAUGHT BY RENDERING LIBRARY ╞═════════════════════════════════════════════════════════
I/flutter ( 4734): The following assertion was thrown during performResize():
I/flutter ( 4734): Vertical viewport was given unbounded height.
I/flutter ( 4734): Viewports expand in the scrolling direction to fill their container.
////MORE LINES OF ERRORS/////
Here's the code I have been working on:
import 'package:flutter/material.dart';
void main() {
runApp(ListDemo(
items: new List<ListItem>.generate(
100,
(i) => i % 6 == 0
? new HeadingItem("Heading $i")
: new MessageItem("Sender $i", "Message body $i"),
),
));
}
// The base class for the different types of items the List can contain
abstract class ListItem {}
// A ListItem that contains data to display a heading
class HeadingItem implements ListItem {
final String heading;
HeadingItem(this.heading);
}
// A ListItem that contains data to display a message
class MessageItem implements ListItem {
final String sender;
final String body;
MessageItem(this.sender, this.body);
}
class ListDemo extends StatelessWidget {
final List<ListItem> items;
ListDemo({Key key, #required this.items}) : super(key: key);
#override
Widget build(BuildContext context) {
final ListView listView = ListView.builder(
itemCount: items.length,
itemBuilder: (context, index) {
final item = items[index];
if (item is HeadingItem) {
return new ListTile(
title: new Text(
item.heading,
style: Theme.of(context).textTheme.headline,
),
);
} else if (item is MessageItem) {
return new ListTile(
title: new Text(item.sender),
subtitle: new Text(item.body),
);
}
},
);
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('Lists'),
),
body: ListView( //Tried using ListView, Column.. None of them help solving the issue
children: <Widget>[
RaisedButton(
onPressed: null,
child: Text('Sample Button'),
),
Container(
child: listView,
)
]
)
)
);
}
}
Please help me solve this issue of letting know, how to pass multiple children, and also please make understand the concept as well.
EDITED
One of the possible solutions suggested wrapping ListView with Expanded class. When I did it threw me an error as below:
I/flutter ( 4190): ══╡ EXCEPTION CAUGHT BY WIDGETS LIBRARY ╞═══════════════════════════════════════════════════════════
I/flutter ( 4190): The following assertion was thrown building NotificationListener<KeepAliveNotification>:
I/flutter ( 4190): Incorrect use of ParentDataWidget.
I/flutter ( 4190): Expanded widgets must be placed inside Flex widgets.
I/flutter ( 4190): Expanded(no depth, flex: 1, dirty) has no Flex ancestor at all.
So I wrapped the entire Widget code in Flex as below:
Flex(
direction: Axis.vertical,
children: <Widget>[
ListView(
children: <Widget>[
RaisedButton(
onPressed: null,
child: Text('Snackbar'),
),
Expanded(
child: listView
)
],
)
],
)
but then it threw me this error:
I/flutter ( 4388): ══╡ EXCEPTION CAUGHT BY RENDERING LIBRARY ╞═════════════════════════════════════════════════════════
I/flutter ( 4388): The following assertion was thrown during performResize():
I/flutter ( 4388): Vertical viewport was given unbounded height.
I/flutter ( 4388): Viewports expand in the scrolling direction to fill their container.In this case, a vertical
I/flutter ( 4388): viewport was given an unlimited amount of vertical space in which to expand. This situation
I/flutter ( 4388): typically happens when a scrollable widget is nested inside another scrollable widget.
This question is already answered here
Can't add a ListView in Flutter
If you use a scrollable view(Listview) inside another scrollable view, the inner scrollable view doesn't know how much height it should occupy. You can tell the inner scrollable view about how much height it should take using an Expanded widget.

Resources