I am trying to add a Row inside of a list view and am getting the error
I/flutter (13858): ══╡ EXCEPTION CAUGHT BY RENDERING LIBRARY ╞═════════════════════════════════════════════════════════
I/flutter (13858): The following assertion was thrown during performLayout():
I/flutter (13858): BoxConstraints forces an infinite height.
I/flutter (13858): These invalid constraints were provided to RenderParagraph's layout() function by the following
I/flutter (13858): function, which probably computed the invalid constraints in question:
I/flutter (13858): RenderFlex.performLayout (package:flutter/src/rendering/flex.dart:805:17)
I/flutter (13858): The offending constraints were:
I/flutter (13858): BoxConstraints(w=72.0, h=Infinity)
Following the guidance found for that error, I have tried wrapping my ListView in an Expanded, but that only leads to Expanded widgets must be placed inside Flex widgets., which leads me to trying another approach.... and ending up back with this same error.
My widget is below. Is there a way to get this working? What I am ultimately trying to do is show multiple sets of rows with some text between between them, allowing for the user to scroll the page up and down.
class _RoutineEditState extends State<RoutineEdit> {
String routineName;
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Edit Routine'),
),
body: ListView(
//padding: EdgeInsets.fromLTRB(10, 15, 10, 5),
children: <Widget>[
Text('ddedede'),
Row(
crossAxisAlignment: CrossAxisAlignment.stretch,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text('Set'),
],
),
],
),
);
}
}
As I am not aware of your desired layout.
Just to fix the error. we have three options.
First: use - IntrinsicHeight widget.
code:
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Edit Routine'),
),
body: ListView(
//shrinkWrap: true,
//padding: EdgeInsets.fromLTRB(10, 15, 10, 5),
children: <Widget>[
Text('ddedede'),
IntrinsicHeight(
child: Row(
crossAxisAlignment: CrossAxisAlignment.stretch,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text('Set'),
Text('Set'),
Text('Set'),
],
),
),
],
),
);
}
Second: wrap your row in LimitedBox and keep - crossAxisAlignment: CrossAxisAlignment.stretch
code:
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Edit Routine'),
),
body: ListView(
shrinkWrap: true,
//padding: EdgeInsets.fromLTRB(10, 15, 10, 5),
children: <Widget>[
Text('ddedede'),
LimitedBox(
maxHeight: 200.0,
child: Row(
crossAxisAlignment: CrossAxisAlignment.stretch,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text('Set'),
Text('Set'),
Text('Set'),
],
),
),
],
),
);
}
Third: remove or comment - crossAxisAlignment: CrossAxisAlignment.stretch
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Edit Routine'),
),
body: ListView(
shrinkWrap: true,
//padding: EdgeInsets.fromLTRB(10, 15, 10, 5),
children: <Widget>[
Text('ddedede'),
Row(
// crossAxisAlignment: CrossAxisAlignment.stretch,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text('Set'),
Text('Set'),
Text('Set'),
],
),
],
),
);
}
Expanded widget must be the child of Row or Column widgets, but you have used it directly in body property. Try to remove the first Expanded widget.
Scaffold(
appBar: AppBar(
title: Text('Edit Routine'),
),
body: ListView(
//padding: EdgeInsets.fromLTRB(10, 15, 10, 5),
children: <Widget>[
Text('ddedede'),
Row(
crossAxisAlignment: CrossAxisAlignment.stretch,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Flexible(
flex: 1,
child: Text('Set'),
fit: FlexFit.tight,
),
Flexible(
flex: 1,
child: Text('Reps'),
fit: FlexFit.tight,
),
Flexible(
flex: 1,
child: Text('lbs'),
fit: FlexFit.tight,
),
Flexible(
flex: 1,
child: Text('prev'),
fit: FlexFit.tight,
),
Flexible(
flex: 1,
child: Text('...'),
fit: FlexFit.tight,
),
],
),
// Column(
// crossAxisAlignment: CrossAxisAlignment.start,
// children: <Widget>[
// SizedBox(
// height: 24,
// ),
// TextField(
// controller: TextEditingController(text: routineName),
// keyboardType: TextInputType.text,
// decoration: kTextFieldDecoration.copyWith(hintText: 'Name of routine')),
// SizedBox(
// height: 24,
// ),
// ],
// ),
],
),
);
Related
I can't work this out. It should be really simple. (This is Flutter Desktop)
I want a Row with 2 columns. The first column should be full height available but only 200 wide. Column 2 should be full height and use the remainder of the width.
I have tried all sorts but always get an overflow rather than a scrollable list.
What am I doing wrong?
This is the last iteration of my code.
class HomePage extends StatelessWidget {
const HomePage({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Bnode Management'),
),
body: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text('This is the title'),
Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Expanded(
child: Container(
width: 200,
child: ListView.builder(
shrinkWrap: true,
itemCount: piItems.length,
itemBuilder: (BuildContext context, int index) {
return Container(width: 40, color: Colors.red, child: Text(piItems[index].id));
}),
),
),
Container(color: Colors.blue, child: const Text('Column 1')),
],
),
],
),
);
}
}
The second Column like to have max space, therefor we can use Expanded on it instead of using on 1st Column. Also, the Row is needed to have max height. For this, we will wrap this Row with Expanded.
body: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text('This is the title'),
Expanded(
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
width: 200,
child: ListView.builder(
shrinkWrap: true,
itemCount: piItems.length,
itemBuilder: (BuildContext context, int index) {
return Container(
width: 40,
color: Colors.red,
child: Text(piItems[index].id));
}),
),
Expanded(
child: Container(
color: Colors.blue,
child: Column(
children: [
const Text('Column 1'),
],
),
),
)
],
),
),
],
),
I also prefer using LayoutBuilder on body in this case.
You almost got it right, just mixed some things. Let's go step by step.
I want a Row with 2 columns
Ok, that's just a Row with two children.
Row(
children: [child1, child2],
)
The first column should be full height available but only 200 wide.
It would take the full height automatically but I see that in your code example you have a Column with Text title, so we should wrap our Row with Expanded. Also, the first Column should take 200 px.
Column(
children: [
const Text('This is the title'),
Expanded(
child: Row(
children: [
Container(
width: 200,
child: child1,
),
child2,
],
),
),
],
)
Column 2 should be full height and use the remainder of the width.
So we wrap our 2nd child with Expanded inside the Row.
Column(
children: [
const Text('This is the title'),
Expanded(
child: Row(
children: [
Container(
width: 200,
child: child1,
),
Expanded(
child: child2,
),
],
),
),
],
)
The end result based on your code:
class HomePage extends StatelessWidget {
const HomePage({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Bnode Management'),
),
body: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text('This is the title'),
Expanded(
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
width: 200,
child: ListView.builder(
shrinkWrap: true,
itemCount: piItems.length,
itemBuilder: (BuildContext context, int index) {
return Container(
width: 40,
color: Colors.red,
child: Text(piItems[index].id));
},
),
),
Expanded(
child: Container(
color: Colors.blue,
child: const Text('Column 1'),
),
),
],
),
),
],
),
);
}
}
I am making a flutter layout with several items in it. It is a column with several widgets among them a gridview containing several items. I would like to make the whole layout scrollable however even after wrapping the main widget in a singlechildscrollview it is not scrollable
This is the code
class _CustomerDataState extends State<CustomerData> {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Customer Data'),
centerTitle: true,
),
body: _containers());
}
Widget _containers() {
return Container(
alignment: Alignment.center,
child: Column(
// mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Card(elevation: 5.0, child: Text('Information')),
Card(
elevation: 5.0,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[Text('No: '), Text('....')],
),
),
Card(
elevation: 5.0,
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[Text('Stages: '), Text('....')],
),
),
GridView.count(
shrinkWrap: true,
crossAxisCount: 3,
childAspectRatio: 1.0,
padding: const EdgeInsets.all(4.0),
mainAxisSpacing: 4.0,
crossAxisSpacing: 4.0,
children: <Widget>[
Card(
elevation: 5.0,
child: Column(
children: <Widget>[
Icon(Icons.monetization_on),
Text('First Stage')
],
)),
],
),
Row(
children: <Widget>[
Card(
elevation: 8.0,
child: Text('Words here'),
),
Card(
elevation: 8.0,
child: Text('Words here'),
),
],
)
],
),
);
}
}
And is there a way I can center the icon and text in the card widget?
the ScrollController is the one responsible for scrolling behavior, yet your gridview is not using one, consider creating a ScrollController and assign it to the gridview
ScrollController _scrollControllerGridView` = ScrollController()
GridView.count(
shrinkWrap: true,
controller: _scrollControllerGridView,
crossAxisSpacing: 4.0,
...
and to center the card's text and icon
just add
mainAxisAlignment: MainAxisAlignment.center,
to the Column, like this:
Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Icon(Icons.monetization_on),
Text('First Stage')
],
)
I am trying to build a view as in the image below.
The tweet your reply is just stack at the bottom while the other stuff are scrollable.
I've been banging my head on how to achieve this for a couple of hours.
Exactly;y like in the image below. There are four sections:
The post (tweet)
The row of icons
The comments (which scrolls)
The tweet your reply which is static
The solution would be to use the Align Widget. So in your Stack you would put as the last element in the stack:
Align(
alignment: Alignment.bottomCenter,
child: // your widget would go here
),
I'm judging by your question that you have figured out how to do all of the other parts, and was just wondering about the bottom part. You can use Align to align things in other ways as well (such as topCenter, bottomLeft, etc). Hope this helps, and if so please up vote and accept as answer and if not leave a comment below.
Edit:
I wouldn't use a Stack. I would wrap the entire widget tree in a Column, and put the post in a Expanded Widget with a flex factor of 1, and a Row of Icons below it. Then put a ListView in an Expanded Widget with a flex of 4 (you can experiment with values). And lastly in the Column I would add you "Tweet you reply" Widget.
Simple layout code to give you an idea of how to implement it:
Column(
children: <Widget>[
Expanded(
child: ListView(
shrinkWrap: true,
children: <Widget>[
//your post
Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
// your icons
],
),
//your comments
],
),
),
Align(
alignment: Alignment.bottomCenter,
child: // you textField,
),
],
)
Try this
class Home extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Expanded(
child: Column(
children: <Widget>[
Container(
padding: EdgeInsets.all(50),
child: Center(
child: Text(
"A POST"
),
),
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
Icon(Icons.details),
Icon(Icons.print),
Icon(Icons.translate),
Icon(Icons.map)
],
),
Expanded(
child: ListView(
children: List.generate(10, (index) => ListTile(title: Text("Comment $index"),)),
),
)
],
),
),
TextField(
decoration: InputDecoration(
labelText: "Tweet your reply"
),
)
],
),
),
);
}
}
The output:
If you want the post to scroll with it, this should help
import 'package:flutter/material.dart';
class Home extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
mainAxisSize: MainAxisSize.max,
children: <Widget>[
Expanded(
child: SingleChildScrollView(
child: Column(
children: <Widget>[
Container(
padding: EdgeInsets.all(50),
child: Center(
child: Text(
"A POST"
),
),
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
Icon(Icons.details),
Icon(Icons.print),
Icon(Icons.translate),
Icon(Icons.map)
],
),
Column(
children: List.generate(10, (index) => ListTile(title: Text("Comment $index"),)),
)
],
),
),
),
TextField(
decoration: InputDecoration(
labelText: "Tweet your reply"
),
)
],
),
),
);
}
}
in this simplified code i have two TextFormField into one of flutter PageView pages, that they are into another class which that extended from Container, not any Scaffold, now when i click into one of this TextFormFields, resizeToAvoidBottom* don't work in my code
Widget build(BuildContext context) {
return Consumer<ThemeManager>(builder: (context, theme, child) {
return Directionality(
textDirection: TextDirection.rtl,
child: Scaffold(
key: _scaffoldKey,
backgroundColor: theme.accentColor,
resizeToAvoidBottomPadding: false,
resizeToAvoidBottomInset: false,
body: NotificationListener<OverscrollIndicatorNotification>(
onNotification: (overScroll) {
overScroll.disallowGlow();
return false;
},
child: Container(
width: double.infinity,
height: double.infinity,
child: IntrinsicHeight(
child: Stack(
children: <Widget>[
Container(
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height - 50,
child: Column(
mainAxisSize: MainAxisSize.max,
children: <Widget>[
BuildLoginHeaderScreen(theme: theme),
Expanded(
child: PageView(
controller: _pageController,
children: <Widget>[
... // contains two TextFormFields
],
),
),
],
),
),
],
),
),
),
),
),
);
});
}
You can go around using resizeToAvoidBottomPadding by wrapping appropriate part of your code with SingleChildScrollView. For example
child: SingleChildScrollView(
child: Column(
mainAxisSize: MainAxisSize.max,
children: <Widget>[
BuildLoginHeaderScreen(theme: theme),
Expanded(
child: PageView(
controller: _pageController,
children: <Widget>[
... // contains two TextFormFields
],
),
),
],
),
),
This will prevent pixel overflow when the keyboard reduces the view area.
I am trying to extract re-use a simple widget that is then referenced in parent widget. The custom widget simply uses a row to layout a textField and a button, and below this I Want to have a listview showing items. I then embed in the customwidget in parent, but it continually throws Error. I have not figured out how to get the custom widget working where I can use ListView or column layout inside. Below is the 2 simplified widgets that demo the issue.
Here is the parent widget, which is where I call the custom widget PlayListControl()
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('My Playlists'),
),
body: Container(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
textDirection: TextDirection.ltr,
children: <Widget>[
Container(
alignment: Alignment.center,
margin: EdgeInsets.all(20),
child: Text('Test'),
),
PlayListControl(),
],
),
),
drawer: SideDrawer(),
);
}
}
And here is the playlistcontrol widget.
#override
Widget build(BuildContext context) {
return Container(
margin: EdgeInsets.all(10),
child: Column(
children: <Widget>[
Container(
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Container(
width: 200,
child: TextField(),
),
ButtonTheme(
minWidth: 30,
child: RaisedButton(
textColor: Colors.white,
child: Text('add'),
onPressed: () {},
)),
],
),
),
Expanded(
child: ListView(
children: <Widget>[
Text('Widget 1'),
Text('Widget 2'),
],
),
)
],
),
);
}
}
No matter what I try, it always complains about layout issue related to height. I would have thought wrapping the ListView in Expanded would solve the issue, but it doesn't. Only if I use a container and specify height do I not get the errors, but I want to use whatever available space there is.
How can I get this playlistcontrol() widget to properly render inside a parent control?
you forgot to wrap the first container of PlayListControl in Expanded widget..
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
home: Scaffold(
appBar: AppBar(
title: Text('My Playlists'),
),
body: Container(
child: Column(
mainAxisSize: MainAxisSize.max,
crossAxisAlignment: CrossAxisAlignment.start,
textDirection: TextDirection.ltr,
children: <Widget>[
Container(
alignment: Alignment.center,
margin: EdgeInsets.all(20),
child: Text('Test'),
),
PlayListControl(),
],
),
),
));
}
}
class PlayListControl extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Expanded(
child: Container(
margin: EdgeInsets.all(10),
child: Column(
children: <Widget>[
Container(
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Container(
width: 200,
child: TextField(),
),
ButtonTheme(
minWidth: 30,
child: RaisedButton(
textColor: Colors.white,
child: Text('add'),
onPressed: () {},
)),
],
),
),
Expanded(
child: ListView(
children: <Widget>[
Text('Widget 1'),
Text('Widget 2'),
],
),
)
],
),
),
);
}
}