Stretch and start FlatButton.icon - flutter

In a Column there's a group of FlatButtons created with FlatButton.icon()
so that it has image and text laid beside each other,
I need the FlatButton's contents to be aligned to the left, but the button is stretched horizontally,
setting the column's crossAxisAlignment to CrossAxisAlignment.stretch stretches the button's width as I want, but centers the button's content:
and setting it to CrossAxisAlignment.start aligns the button's contents to the left but the button's width gets shrinked:
is it possible to align the button contents to the left but the button be stretched? or I have to use other combinations of widgets (InkWell for example?)

you can use a normal FlatButton() constructor that has the child property and then you can have a row as the child and make it's mainAxisAlignment:MainAxisAlignment.start and make your text and icon it's children's, like below:
Scaffold(
body: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
FlatButton(
color: Colors.grey,
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Icon(Icons.check),
SizedBox(width: 10),
Text('Recharge and balance')
],
), onPressed: () {},
)
],
),
)
the result:

It is a bit of a hack, but you could use a regular FlatButton widget and do something like this could work:
class SampleWidget extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
ConstrainedBox(
constraints: BoxConstraints(
maxWidth: 200,
),
child: FlatButton(
onPressed: () {},
child: Row(
children: <Widget>[
Icon(Icons.home),
Text('Recharge and balance'),
Spacer(),
],
),
),
),
],
);
}
}
Spacer widget will take up the remaining space of row. All you have to do from here is just adjust the padding of the Icon to be the same as FlatButton.icon

Try changing padding property of Flatbutton to Edgeinsets.only(left: 0.0)
padding: Edgeinsets.only(left: 0.0),

Related

Flutter: Cant align row items correctly

I have a row im trying to align correctly. It holds two cards id like to be spaced evenly, and an icon button aligned to the right side of the row.
With just the cards using the following code,
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Card(...),
Card(...),
],
),
it looks like this:
But When i add an icon button with the following code
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Card(),
Card(),
Spacer(),
IconButton(
icon: Icon(Icons.close),
onPressed: () {
Navigator.of(context).pop();
},
),
],
),
it looks like this:
Any idea what I'm doing wrong? Thanks!
A note from Spacer
MainAxisAlignment.spaceBetween, or MainAxisAlignment.spaceEvenly will not have any visible effect: the Spacer has taken up all of the additional space, therefore there is none left to redistribute.
As for the you are trying to archive, I am using nested row for this
Row(
children: [
Expanded(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Card(
child: Text("A"),
),
Card(
child: Text("A"),
),
],
),
),
IconButton(
icon: Icon(Icons.close),
onPressed: () {},
),
],
),
It is caused by the Spacer widget.
The Spacer widget will use all the space available by default.
You can remove the Spacer widget so all your child will be evenly-spaced.
It is because of the spacer widget, Spacer widget by default took the whole width. give it a specific width, instead use sizedBox and give it a width for horizontal space.

how can I show long texts so that they continue from the bottom line

I want the long texts to be clipped and continue from the down line. How can I do this in flutter?
I have tried all the features of "textoverflow" but no changes
ListTile(
onTap: () {},
visualDensity: VisualDensity(vertical: 4),
leading: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
Expanded(
child: Text(
"Cari Kodu: ${item.cariKod.toString()}",
),
),
],
),
trailing: Column(
crossAxisAlignment: CrossAxisAlignment.end,
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
Text(
"Bakiye: ${item.bakiye.toString()}" +
"${item.dovizIdStr != null ? " ${item.dovizIdStr}" : ""}",
),
],
),
),
just wrap your text inside an Expanded. because the Text widget is inside a Row the widget doesn't know how much horizontal space it has.
ConstrainedBox( constraints: BoxConstraints.expand(width: // your Width //),child:// your TextWidget //)
you can try this with ConstrainedBox Widget you have to give the width whatever you want, it will be automatically wrapped the text inside the given width

Why FlatButton takes more space than it should?

The space around FlatButton is bigger than the space between Containers in the column with spaceEvenly alignment. This flatbutton contains nothing except a text widget. Does it use some default padding or something else which takes extra space?
Widget build(BuildContext context) {
return Scaffold(
body: Container(
decoration: const BoxDecoration(...),
constraints: const BoxConstraints.expand(),
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Container(...),
Container(...),
FlatButton(...),
],
),
),
),
);
}
FlatButton comes with some internal padding, which is like 8px of padding on each side, and for the text is 20px high.
FlatButton(
padding: EdgeInsets.zero, // Will add default padding as zero
child: ...,
)
Yes it has a default internal padding, use this to remove it
FlatButton(materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,)
Use this code :
FlatButton(
padding: EdgeInsets.all(0),
materialTapTargetSize: MaterialTapTargetSize.shrinkWrap
)

How to position a Widget at the bottom of a SingleChildScrollView?

I need to use SingleChildScrollView in order to be able to use keyboard_actions so that i can put a "Done" button on top of the keyboard in iOS (using a numeric keyboard at the moment)
The SingleChildScrollView will have a column as a child and then a button to be placed at the bottom. I tried using LayoutBuilder to enforce a height to the SingleChildScrollView.
LayoutBuilder(
builder: (BuildContext context, BoxConstraints viewportConstraints) {
return SingleChildScrollView(
child: ConstrainedBox(
constraints:
BoxConstraints(minHeight: viewportConstraints.maxHeight),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
mainAxisSize: MainAxisSize.max,
children: <Widget>[
Column(),
// Spacer() ?
FlatButton()
])));
});
I tried using the BoxConstraints with the maxHeight attribute, but ultimately the widget wouldn't scrooll up when the keyboard appeared.
Side note: the Scaffold has both resizeToAvoidBottomInset and resizeToAvoidBottomPadding set to true (the default value)
The issue with SingleChildScrollView is that it shrikwrap it's children.
So to have auto size widget in between - we need to use MediaQuery to get the screen height & SizedBox to expand - SingleChildScrollView.
Here Button will be at bottom of screen.
working Code:
double height = MediaQuery.of(context).size.height;
SingleChildScrollView(
child: SizedBox(
height: height,
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
mainAxisSize: MainAxisSize.max,
children: <Widget>[
Column(
children: <Widget>[
Text('Dummy'),
Text('Dummy'),
Text('Dummy'),
],
),
Spacer(),
FlatButton(
onPressed: () {},
child: Text('Demo'),
)
])),
)
The chosen answer doesn't really work, as using a SizedBox restrict the max size of the Column to the height of the screen, so you can't put as many widgets as you want in it (or they will go off-screen without beeing scrollable).
This solution will work no matter of many widgets are in the column:
https://github.com/flutter/flutter/issues/18711#issuecomment-505791677
Important note: It will only work if the widgets in the column have a fixed height (for example TextInputField does NOT have a fixed height). If they have variable a height, wrap them with a Container of fixed height.
I just copied and pasted here the best solution I found, quoted by #Quentin, elaborated by #NikitaZhelonkin in issue 18711 of Flutter on Github. Simply the perfect solution!
class Home extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('AppBar'),
),
body: LayoutBuilder(builder: (context, constraints) {
return SingleChildScrollView(
child: ConstrainedBox(
constraints: BoxConstraints(minWidth: constraints.maxWidth, minHeight: constraints.maxHeight),
child: IntrinsicHeight(
child: Column(
mainAxisSize: MainAxisSize.max,
children: [
Text('header'),
Expanded(
child: Container(
color: Colors.green,
child: Text('body'),
),
),
Text('footer'),
]
),
)
)
);
})
);
}
}
You may use this workaround appraoch also, You can use padding attribute in SingleChildScrollView like this:
SingleChildScrollView(
padding: EdgeInsets.only(top: height),
child: yourWidgets(),
while height is the distance far away from top.
You can also use this line to get mobile screen height:
double height = MediaQuery.of(context).size.height;
The best solution I have found for myself.
Center the widgets and push them from top to bottom with padding.
return Scaffold(
resizeToAvoidBottomInset: true,
//resizeToAvoidBottomPadding: false,
backgroundColor: PrimaryColor,
body: Center(
SingleChildScrollView(child:
_body())));
Widget _body() {
return Padding(
padding: EdgeInsets.only(top: MediaQuery.of(context).size.height/2.7),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.end,
children: <Widget>[
Text(
'You have pushed the button this many times:',
),
Visibility(
visible:
_userProvider.stateReqVMTokenSocial !=
StateReqVM.Processing,
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
...
...
...
],
)),
Visibility(
visible:
_userProvider.stateReqVMTokenSocial ==
StateReqVM.Processing,
child: CircularProgressIndicator()),
Text(
'',
style: Theme.of(context).textTheme.headline4,
),
],
)
);
}

How to get the smallest child in a box?

Consider
new ListView(
children: <Widget>[
new RaisedButton(child: const Text('1')),
],
)
How to make the button occupy only its natural width?
Consider wrapping your RaisedButton in a Row. In addition to letting the button be its intrinsic width, you can use the Row to position the button horizontally using the mainAxisAlignment constructor argument. e.g. to right-align the button, use this:
new ListView(
children: <Widget>[
new Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
new RaisedButton(
child: const Text('1'),
onPressed: () { /* ... */ },
),
],
),
],
),