Bottom overflow 13 pixels - flutter

How can fix it?
Widget build(BuildContext context) {
final Size size = MediaQuery.of(context).size;
return Scaffold(
resizeToAvoidBottomInset: false,
body: Stack(
fit: StackFit.loose,
children: [
Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Expanded(
flex: 2,
child: buildSearch(),
),
Expanded(
flex: 2,
child: Container(color: Colors.green),
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text('Frequitly Visited'),
TextButton(
onPressed: () {},
child: Text('Show More'),
),
],
),
Expanded(
flex: 6,
child: buildSites(size),
)
],
)
],
),
);
}
buildSearch() {
return Container(
child: FloatingSearchBar(
transitionCurve: Curves.easeInOutCubic,
transition: CircularFloatingSearchBarTransition(),
physics: const BouncingScrollPhysics(),
scrollPadding: EdgeInsets.zero,
builder: (context, _) => _history(),
),
);
}
Container buildSites(size) {
return Container(
color: Colors.black,
width: size.width,
);
}
Widget _history() {
List<String> listHistory = [
'Flutter',
'Python',
'Nodejs',
'Rails',
];
return ClipRRect(
borderRadius: BorderRadius.circular(8),
child: Material(
child: Column(
children: listHistory
.map((e) => ListTile(
title: Text(e),
onTap: () {},
))
.toList(),
),
),
);
}
}

try to fixed the height of search & container, expanded only flexible part:
Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Container(
height: 100,
child: buildSearch(),
),
Container(
height: 100,
child: Container(color: Colors.green),
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text('Frequitly Visited'),
TextButton(
onPressed: () {},
child: Text('Show More'),
),
],
),
Expanded(
child: buildSites(size),
)
],
)

You can just remove the Expanded widget wrapped around your buildSearch() widget and give a desired padding or you can also your sizedbox with a desiredHeight below and above the buildSearch()
so basically change
...
Expanded(
flex: 2,
child: buildSearch(),
),
...
to
...
Padding(
padding:EdgeInsets.only(top:20,bottom:50), // adding a suitable padding should fix it
child:buildSearch(),
)
...

Related

ListView with Expanded when not scrollable

I want to make a menu with list of ExpansionTile and a footer, when the ExpansionTile is not expanded (not scrollable) the footer stay on the bottom of screen, but when the ExpansionTile is expanded (scrollable) the children of ExpansionTile push the footer out of screen.
For a clearer illustration, please see the following image
this my current code, but it's not a best way I think
checking is scrollable or not
checkIsScrollable(BuildContext context) {
if (Scrollable.of(context).position.minScrollExtent >=
Scrollable.of(context).position.maxScrollExtent) {
setState(() {
scrollable = false;
});
} else {
setState(() {
scrollable = true;
});
}
this the listview
ListView(
padding: EdgeInsets.symmetric(horizontal: 16),
children: [
LimitedBox(
maxHeight: !scrollable
? MediaQuery.of(context).size.height - 84
: double.infinity,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SizedBox(
height: 24,
),
Text(
"Account".toUpperCase(),
style: ThemeApp.appBarTextStyle(),
),
SizedBox(
height: 24,
),
photoProfile(),
SizedBox(
height: 40,
),
menuProfile(),
SizedBox(
height: 40,
),
AccountContent.customerCare1(
context: context,
onExpansionChanged: (_) {
Future.delayed(
Duration(milliseconds: 101),
() {
checkIsScrollable(context);
},
);
},
),
AccountContent.sellWithUs(
context: context,
onExpansionChanged: (_) {
Future.delayed(
Duration(milliseconds: 101),
() {
checkIsScrollable(context);
},
);
},
),
AccountContent.customerCare2(
context: context,
onExpansionChanged: (_) {
Future.delayed(
Duration(milliseconds: 101),
() {
checkIsScrollable(context);
},
);
},
),
!scrollable
? Expanded(
child: Container(),
)
: Container(),
Container(
padding: EdgeInsets.symmetric(vertical: 16),
child: Column(
children: [
InkWell(
child: Row(
children: [
Container(
height: 18,
width: 18,
color: ThemeApp.borderColor,
),
SizedBox(width: 10),
Text(
"LOGOUT",
style: ThemeApp.subTitleTextStyle(),
),
],
),
onTap: () {},
),
SizedBox(
height: 20,
),
Row(
children: [
Expanded(
child: BorderedButton(
child: SvgPicture.asset(
"assets/icons/icon_whatsapp.svg",
color: ThemeApp.primaryColor,
),
onTap: () {
openWhatsapp();
},
),
),
SizedBox(
width: 17,
),
Expanded(
child: BorderedButton(
child: SvgPicture.asset(
"assets/icons/icon_instagram.svg",
color: ThemeApp.primaryColor,
),
onTap: () {
openInstagram();
},
),
),
SizedBox(
width: 17,
),
Expanded(
child: BorderedButton(
child: SvgPicture.asset(
"assets/icons/icon_mail.svg",
color: ThemeApp.primaryColor,
),
onTap: () {
openMail();
},
),
),
],
),
],
),
)
],
),
),
],
);
You should use a Column inside of LayoutBuilder and with a ConstrainedBox, set The minHeight of the Column to maxHeight of LayoutBuilder:
Widget build(BuildContext context) {
return LayoutBuilder(
builder: (BuildContext context, BoxConstraints viewportConstraints) {
return SingleChildScrollView(
physics: const AlwaysScrollableScrollPhysics(),
child: ConstrainedBox(
constraints: BoxConstraints(
minHeight: viewportConstraints.maxHeight,
),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
YourListView(
physics: NeverScrollableScrollPhysics(),
shrinkWrap: true,
),
YourFooter(),
],
),
),
);
},
);
}
I didn't get your question correctly but i guess you need too use Stack widget which always stays your footer on it's place even your page is Scrollable.
The footer you don't want to scroll, make the Column having two children and inside the column add another column and put the scrollable data inside that and wrap that with the SingleChildScrolView.
Column(
children: [
SingleChildScrollView(
child: Column(
children: [
// your scrollable data here
],
Column(
children: [
// Footer not scrollable
],),
],

TabBar in the middle of the screen

I'm trying to put a TabBar in the middle of the screen to make a personal area view. Every time I run the code its jumps me up an exception.
The problem comes in the Tabbar the part above is just the name of the user and the Avatar but when I try to put the appbar it throws me this "throw constraintsError;"
Here is the source code which I use to make the view:
class PersonalArea extends StatelessWidget {
#override
Widget build(BuildContext context) {
String _viewSelector = "personalData";
late Color color = Colors.white;
return new Scaffold(
body: StoreConnector<AppState, PersonalAreaViewModel>(
onInit: (store) {
store.dispatch(new GetPersonalAreaAction());
},
converter: (store) => PersonalAreaViewModel.fromStore(store),
builder: (context, viewModel) => Column(children: [
Stack(children: [
Container(
width: double.infinity,
padding: EdgeInsets.only(left: 4, right: 4),
child: Column(
children: [
Container(
height: MediaQuery.of(context).size.height / 2,
child: Column(
mainAxisSize: MainAxisSize.min,children: [
Stack(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
avatar(),
],
),
Align(
alignment: Alignment.topRight,
child: edit(),
)
],
),
//Avatar&Edit
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
padding: EdgeInsets.only(top: 12),
child: generateStyleText(
"${FirebaseAuth.instance.currentUser?.displayName}",
color.primary75,
FontWeight.w700,
0,
16,
0),
)
],
),
//Name
]), //MainColumn
),
DefaultTabController(
length: 3,
child: Container(
child: Column(
children: [
TabBar(
tabs: [
Tab(
text: "Experiencia",
),
Tab(
text: "Area",
),
Tab(
text: "pedro",
),
],
indicatorSize: TabBarIndicatorSize.tab,
),
Expanded(
child: TabBarView(
children: [
Text('people'),
Text('Person'),
Text("data"),
],
),
)
],
),
))
],
),
)
])
])));
}
Wrap the DefaultTabController with Expanded

Images don't displayed on screen

I have modified my code. I thought I could achieve what I am willing to do but I am still having an issue. The first image is fine, but when I am adding more images, they don't display to the screen. The idea is to allow the user to click on a button to select one or several images. Then, he can tap on a second button and add one pfd file, it is like adding attachment in email.Then, if the user wants he can tap on the first button and add an other image. The list of all the documents should be displayed on the screen. I though that maybe a set State is missing somewhere. Here is the code. I do not understand where is my mistake. Thank you in advance.
import 'dart:io';
import 'package:file_picker/file_picker.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
List<PlatformFile>? _paths;
List<String> filesGB =[];
bool _loadingPath = false;
String fileExtension='';
String _fileName='';
// To access the pictures
void _openPictureFileExplorer() async {
setState(() => _loadingPath = true);
try {
_paths = (await FilePicker.platform.pickFiles(
type: FileType.media,
allowMultiple: true,
))?.files;
if (_paths != null) {
_paths!.forEach((element) {
filesGB.add(element.path.toString());
print(filesGB);
print(filesGB.length);
});
setState(() {
});
}
} on PlatformException catch (e) {
print("Unsupported operation" + e.toString());
} catch (ex) {
print('$ex');
}
if (!mounted) return;
setState(() {
_loadingPath = false;
});
}
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
key: _scaffoldKey,
appBar: AppBar(
title: const Text('File Picker app'),
),
body: Center(
child: Padding(
padding: const EdgeInsets.only(left: 10.0, right: 10.0),
child: SingleChildScrollView(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Padding(
padding: const EdgeInsets.only(top: 20.0),
//#############
//Display card with button to select type of document
child: Card(
child:
Container(
// color: Colors.red,
alignment: Alignment.center,
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
//Attachement
FlatButton(
onPressed: () {},
child:
InkWell(
child: Container(
// color: Colors.white,
child: Column(
mainAxisAlignment: MainAxisAlignment
.center,
children: [
Icon(Icons.attach_file),
Text('Attachment'),
],
)
),
onTap: () async {
fileExtension = 'pdf';
_openDocumentFileExplorer();
},
),
),
//Photo
FlatButton(
onPressed: () {},
child:
InkWell(
child: Container(
// color: Colors.white,
child: Column(
mainAxisAlignment: MainAxisAlignment
.center,
children: [
Icon(Icons.add_a_photo_rounded),
Text('Photo'),
],
)
),
onTap: () {
fileExtension = 'jpeg';
_openPictureFileExplorer();
},
),
),
],
),
)),
),
Builder(
builder: (BuildContext context) => _loadingPath ?
Padding(
padding: const EdgeInsets.only(bottom: 10.0),
child:const CircularProgressIndicator(),
)
: filesGB.isNotEmpty ?
Column(
children: listOfCards(filesGB),
)
:Text('Nothing to display'),
),
]),)))));
}
}
List<Widget> listOfCards(List<String> item){
List<Widget> list = <Widget>[];
ListView.builder(
itemCount: filesGB.length,
itemBuilder: (BuildContext ctxt, int index) {
return new Container(
height: 114,
child: GestureDetector(
child: Card(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(15.0),
),
elevation: 10,
child: ClipPath(
clipper: ShapeBorderClipper(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(15))),
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.start,
children: [
Container(
height: 113, width: 113,
child: Image.file(File(item[i].toString()),
fit: BoxFit.fill,
width: double.infinity,),
),
Expanded(
child: Padding(
padding: const EdgeInsets.all(10.0),
child: Text(item[i]
.split('/')
.last),
),
),
],
),
),),
),
);
});
return list;
}
first of all, you don't need to use for loop for building your pictures list
just use ListView.builder
but about your problem, I think it happens because you set selected pictures in a row
then return that row as a child of your column
so your pictures align horizontally and column just show widgets in vertical aligns
in other words, your column just have one child, and its a Row
so column just show pictures as possible then you just see the first picture.
for solving this problem you should return a list of widgets in the listOfCards function
just do these simple changes and I hope your problem solved
change your function return parameter to List<Widget>
Widget listOfCards(List<String> item) {
to
List<Widget> listOfCards(List<String> item) {
then just return your list
return list;
and your column should look like this
Column(
children: listOfCards(filesGB),
)
I have find a working solution. It does what I was expecting with image. I still have a problem when I delete a record, the card is not removed. I do not find where I should use the setState. I will continue to investigate.
body: Center(
child: Padding(
padding: const EdgeInsets.only(left: 10.0, right: 10.0),
child: SingleChildScrollView(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Padding(
padding: const EdgeInsets.only(top: 20.0),
//#############
//Display card with button to select type of document
child: Card(
child:
Container(
// color: Colors.red,
alignment: Alignment.center,
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
//Attachement
FlatButton(
onPressed: () {},
child:
InkWell(
child: Container(
// color: Colors.white,
child: Column(
mainAxisAlignment: MainAxisAlignment
.center,
children: [
Icon(Icons.attach_file),
Text('Attachment'),
],
)
),
onTap: () async {
fileExtension = 'pdf';
_openDocumentFileExplorer();
},
),
),
//Photo
FlatButton(
onPressed: () {},
child:
InkWell(
child: Container(
// color: Colors.white,
child: Column(
mainAxisAlignment: MainAxisAlignment
.center,
children: [
Icon(Icons.add_a_photo_rounded),
Text('Photo'),
],
)
),
onTap: () {
fileExtension = 'jpeg';
_openPictureFileExplorer();
},
),
),
],
),
)),
),
Builder(
builder: (BuildContext context) => _loadingPath ?
Padding(
padding: const EdgeInsets.only(bottom: 10.0),
child:const CircularProgressIndicator(),
)
: filesGB.isNotEmpty ?
Column(
children: getList(),//[listOfCards(filesGB)],
)
:Text('Nothing to display'),
),
]),)))));
}
}
List<Widget> getList() {
List<Widget> childs = [];
for (var i = 0; i < filesGB.length; i++) {
childs.add(
GestureDetector(
onTap: (){
print ("Pressed");
},
child: Card(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(15.0),
),
elevation: 10,
child: ClipPath(
clipper: ShapeBorderClipper(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(15))),
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.start,
children: [
Container(
height: 113,width: 113,
child: fileExtension == 'pdf'?
Image.asset('assets/logo_pdf.png',
// fit: BoxFit.fill,
// width: double.infinity,
):
Image.file(File(filesGB[i].toString()),
fit: BoxFit.fill,
width: double.infinity,),
),
Expanded(
child: Padding(
padding: const EdgeInsets.all(10.0),
child: Text(filesGB[i].toString().split('/').last,//_nameOfFile,//name,
style: TextStyle(fontWeight: FontWeight.bold),),
),
),
Padding(
padding: const EdgeInsets.only(right:25.0),
child: IconButton(onPressed: (){
//delete a record and the card displaying this record
// Delete the selected image
// This function is called when a trash icon is pressed
if (filesGB.length > 1) {
filesGB.removeAt(i);
print(filesGB);
setState(() {});
}
},
icon:Icon (Icons.delete, color: Colors.red,),),
)
],
),
),
//subtitle: Text(path),
),
));}
return childs;
}

Fill ListView tiles vertically by a container - Flutter

I have been trying to put a line indicator on the left most margin of the card in my flutter app. I've tried a lot of things but didn't work.
There's an exact question here, which is actually the same issue I've been trying to solve.
The problem with the accepted solution is that it restricts the height of the hardcoded value, which I don't want. Rather the color should automatically fill the height of the card.
The Problem
I've tried all the three solutions and none of them fit my use case.
Output from first solution
Here I've to hardcode the value to something larger so that all the text being displayed lies well inside it. That's something I feel is not a solution.
Card(
key: ObjectKey(noteList[index]),
elevation: 2.0,
child: IntrinsicHeight(
child: Row(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
Container(
width: 4,
color: Color(noteList[index].intcolor),
),
Flexible(
flex: 100,
child: ListTile(
~~~~~~~~~~~~~~~~~ SNIP ~~~~~~~~~~~~~~~~~~~~~~~~
chip goes outside
Output from Second solution
This doesn't show anything at all.
Card(
key: ObjectKey(noteList[index]),
elevation: 2.0,
child: Row(
children: <Widget>[
Expanded(
flex: 1,
child: Container(
constraints: BoxConstraints.expand(),
color: Color(noteList[index].intcolor),
),
),
Flexible(
flex: 100,
child: ListTile(
~~~~~~~~~~~~~~~~~ SNIP ~~~~~~~~~~~~~~~~~~~~~~~~
No output at all
Output from last solution
There's no color from the container.
There's no color from the container
Thanks a lot.
Update 1 ( Monday, 6 April 2020 8:16 pm GMT )
Added code and repo for easy replication.
Repo
main.dart
import 'package:flutter/material.dart';
void main() {
List<String> notes = [
"fluttermaster.com",
"Update Android Studio to 3.3",
"Something long Something long Something long Something long Something long Something long",
];
runApp(MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text("Simple Note ListView"),
),
body: Container(
color: Colors.white10,
padding: EdgeInsets.all(16.0),
child: HomePage(notes)),
),
));
}
class HomePage extends StatelessWidget {
final List<String> notes;
HomePage(this.notes);
Widget build(BuildContext context) {
return ListView.builder(
itemCount: notes.length,
itemBuilder: (context, pos) {
return Padding(
padding: EdgeInsets.only(bottom: 16.0),
child: Card(
elevation: 2.0,
child: Row(
// key: _cardKey,
children: <Widget>[
Flexible(
flex: 1,
child: Container(
// -------------------- This here ----------------------------------------------
// FixMe : This shouldn't be hardcoded, rather it should fill the height of it's parent element, in this case card
// https://medium.com/#diegoveloper/flutter-widget-size-and-position-b0a9ffed9407
height: 71,
color: Colors.green,
// -------------------- This here ----------------------------------------------
),
),
Flexible(
flex: 100,
child: ListTile(
// For center alignment from vertical and horizontal : https://stackoverflow.com/a/51546279
// Since using CircleAvatar does this but it decreases size of icon too : https://github.com/flutter/flutter/issues/16061
leading: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Icon(Icons.receipt),
],
),
title: Text(
notes[pos],
),
subtitle: Row(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Text(notes[pos].substring(0, 10)),
// What is the best way to optionally include a widget in a list of children
// https://github.com/flutter/flutter/issues/3783#issuecomment-506019822
if ((pos % 2) == 0)
Chip(
avatar: CircleAvatar(
backgroundColor: Colors.grey.shade800,
child: Icon(Icons.timer),
),
label: Text('2FA'),
),
],
),
trailing: Padding(
padding: EdgeInsets.all(10),
child: Wrap(
spacing: 10,
direction: Axis.vertical,
alignment: WrapAlignment.spaceEvenly,
children: <Widget>[
IconButton(
icon: Icon(
Icons.check,
color: Colors.grey,
),
onPressed: () {},
)
]),
),
onTap: () {},
),
),
],
),
));
},
);
}
}
Perhaps one way of doing it is to use Stack
ListView.builder(
itemCount: notes.length,
itemBuilder: (context, pos) {
return Padding(
padding: EdgeInsets.all(8),
child: Stack(
children: <Widget>[
Card(
margin: EdgeInsets.zero,
child: ListTile(
leading: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Icon(Icons.receipt),
],
),
title: Text(
notes[pos],
),
subtitle: Row(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Text(notes[pos].substring(0, 10)),
if ((pos % 2) == 0)
Chip(
avatar: CircleAvatar(
backgroundColor: Colors.grey.shade800,
child: Icon(Icons.timer),
),
label: Text('2FA'),
),
],
),
trailing: Padding(
padding: EdgeInsets.all(10),
child: Wrap(
spacing: 10,
direction: Axis.vertical,
alignment: WrapAlignment.spaceEvenly,
children: <Widget>[
IconButton(
icon: Icon(
Icons.check,
color: Colors.grey,
),
onPressed: () {},
)
]),
),
onTap: () {},
),
),
Positioned(
top: 0,
bottom: 0,
child: Container(
width: 5,
color: Colors.green,
),
)
],
),
);
},
)
Output

How can I make the table take the available space along the height?

I have the following table
#override
Widget build(BuildContext context){
final TheGroupPageArguments arguments = ModalRoute.of(context).settings.arguments;
return Scaffold(
body: Padding(
padding: EdgeInsets.all(20.0),
child: Column(
children: [
Flexible(
flex: 1,
child: Align(
alignment: Alignment.center,
child: DigitalSpeedMeter(),
),
),
Flexible(
flex: 6,
child: Table(
children: [
TableRow(children: [backButton(), backButton(), backButton()]),
TableRow(children: [backButton(), backButton(), backButton()]),
],
),
),
]
),
),
);
}
But it only takes half the screen height. How can I make it strecht to it's parent's height?
This is how it looks now
This is what it should look like
This is what it should look like
You can use the "Expanded" instead of "Flexible".
I can't find a good solution.
Anyone know a good way?
#override
Widget build(BuildContext context) {
return Scaffold(
body: Padding(
padding: EdgeInsets.all(20.0),
child: Column(
children: [
Expanded(
flex: 1,
child: Container(
color: Colors.yellow,
child: Align(
alignment: Alignment.center,
child: Text(
'0\nMPH',
textAlign: TextAlign.center,
),
),
),
),
Expanded(
flex: 6,
child: Column(
children: [
Expanded(
child: Row(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Expanded(
child: FlatButton(
onPressed: () {},
color: Colors.tealAccent,
child: Text("button1"),
),
),
Expanded(
child: FlatButton(
onPressed: () {},
color: Colors.green,
child: Text("button2"),
),
),
],
),
),
Expanded(
child: Container(
color: Colors.grey,
child: Row(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Expanded(
child: FlatButton(
onPressed: () {},
color: Colors.blue,
child: Text("button3"),
),
),
Expanded(
child: FlatButton(
onPressed: () {},
color: Colors.amber,
child: Text("button4"),
),
),
],
),
),
),
],
),
),
],
),
),
);
}
I found a solution. How about this?
#override
Widget build(BuildContext context) {
return Scaffold(
body: Padding(
padding: EdgeInsets.all(20.0),
child: Column(children: [
Flexible(
flex: 1,
child: Align(
alignment: Alignment.center,
child: Container(
color: Colors.yellow,
child: Align(
alignment: Alignment.center,
child: Text(
'0\nMPH',
textAlign: TextAlign.center,
),
),
),
),
),
Flexible(
flex: 6,
child: Table(
children: [
TableRow(children: [backButton(), backButton(), backButton()]),
TableRow(children: [backButton(), backButton(), backButton()]),
],
),
),
]),
),
);
}
Widget backButton() {
return Container(
height: MediaQuery.of(context).size.height / 7 * 6 / 2 - 7,
child: FlatButton(
onPressed: () {},
color: Colors.tealAccent,
child: Text("button"),
),
);
}
I ended up doing the following. A widget that makes the rows and columns dynamically based on the the widgets put into it.
import 'package:flutter/material.dart';
class ExpandingGrid extends StatelessWidget {
final List<Widget> tiles;
final int columns;
const ExpandingGrid({this.tiles, this.columns});
int _rows(){
return (tiles.length / columns).ceil();
}
int _tileIndex(int row, int column) => row * columns + column;
Widget _gridTile(int row, int column){
if(_tileIndex(row, column) < tiles.length)
{
return Expanded(
child: tiles[_tileIndex(row, column)],
);
}
return Spacer();
}
#override
Widget build(BuildContext context) {
return Column(
children:
[
for(int r = 0; r < _rows(); r++ )
Expanded(
child: Row
(
children :
[
for(int c = 0; c < columns; c++)
_gridTile(r, c),
]
),
)
]
);
}
}