Flutter - make button fill the entire container - flutter

I am very new to Flutter and I trying to make button fill the entire parent container. I want to create two buttons each of them 50% of device height and 100% width using two Flexible with flex parameters.
This is What I have:
Flexible(
flex: 1,
child: Container(
color: Color.fromARGB(255, 20, 20, 20),
alignment: Alignment.center,
child: ElevatedButton(
child:Text('$_counter1'),
onPressed: _pop1,
),
),
),
Everyday I create websites using CSS and HTML and here in Flutter everything works completly diferent. It's hard to understand the code at the begining. With CSS I cloud only add 100% width and height and done but here I am little bit lost.
This is What I am trying to get:

With flutter, you can use Column, Expanded
Column(
children: [
Expanded(
flex: 1,
child: Container(
color: const Color.fromARGB(255, 20, 20, 20),
alignment: Alignment.center,
child: ElevatedButton(
child: Text('Button 1'),
onPressed: (){},
),
),
),
Expanded(
flex: 1,
child: Container(
color: Colors.green,
alignment: Alignment.center,
child: ElevatedButton(
child: Text('Button 2'),
onPressed: (){},
),
),
),
],
)

you are almost right. Flexible takes only the needed space. if you want to takes all space available like 100% then you need to add another properties for Flexible :
https://stackoverflow.com/a/52646036/12838877
Flexible(
fit: FlexFit.tight,
child: Foo(),
);
or is just shorthand with Expanded
Flexible(
fit: FlexFit.tight,
child: Foo(),
);
for comparison : reff
as you can see, Flexible will only take as minimum space needed.
and by default expanded will take 100% available space.
if you want to modify, you just change the flex value

You could combine Column with cross axis alignment strech to achieve this.
Like so:
Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Expanded(
child: Container(
color: Colors.grey,
child: TextButton(
onPressed: () {},
child: Text(
'Button 1',
style: Theme.of(context).textTheme.headline2!.copyWith(
color: Colors.grey.shade700,
),
),
),
),
),
Expanded(
child: Container(
color: Colors.grey.shade700,
child: TextButton(
onPressed: () {},
child: Text(
'Button 2',
style: Theme.of(context).textTheme.headline2!.copyWith(
color: Colors.grey,
),
),
),
),
),
],
Running example:
https://dartpad.dev/?enchanted-pomelo-5708

Related

How to Locate the Text() center when using expanded(flex:)?

Please see my code and scree shot below. I want locate Text("to be center") at center horizontally, but comparatively located right side as showen below.
I understand i'ts because I'm using expanded widget and set flex 1 & 4 and Text("to be center") are inclueded in latter block.
How can I located totally or relatively center but using expandede & flex property like this case ?
Also I understand I can adjust it by wrapping Text() with padding and set EdgeInsets.only(right:X) but I can not figure out if it is totally cenerized or not...
Row(
children: [
Expanded(
flex:1,
child:TextButton(
style: TextButton.styleFrom(
alignment: Alignment.centerLeft,
),
child: const Icon(
Icons.close,
color: MyStyle.textColor,
),
onPressed: () {
Navigator.of(context).pop();
},
),
),
Expanded(
flex:4,
child: Container(
alignment: Alignment.center,
decoration: const BoxDecoration(
),
child: Text("to be center",style: MyText(myFontSize: 15).style()),
)
),
],
),
Just use Spacer at the end inside Row
Row(
children: [
Expanded(
flex: 1,
child: TextButton(
style: TextButton.styleFrom(
alignment: Alignment.centerLeft,
),
child: const Icon(
Icons.close,
color: MyStyle.textColor,
),
onPressed: () {
Navigator.of(context).pop();
},
),
),
Expanded(
flex: 4,
child: Container(
alignment: Alignment.center,
decoration: const BoxDecoration(),
child: Text(
"to be center",
style: MyText(myFontSize: 15).style(),
),
),
),
// like this
const Spacer(),
],
),
Learn more about the Spacer widget
Try below code: refer layout
Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Expanded(
child: TextButton(
style: TextButton.styleFrom(
alignment: Alignment.centerLeft,
),
child: const Icon(
Icons.close,
),
onPressed: () {
Navigator.of(context).pop();
},
),
),
const Expanded(
child: Center(
child: Text(
'to be center',
),
),
),
const Expanded(child: SizedBox())
],
),
Result->
The simple solutions could be:
Use textAlign attribute of Text widget or
Wrap Text widget with Center widget inside Expanded widget or
You can even explore the widget IntrinsicWidth with Center widget.

How to align an asset image responsive at bottom center in flutter

here is the UI that I'm trying to build
but this is the output
I tried alignment also , but that also didn't working
but when setting a fixed height this is working fine
but I can't fill this using the fit parameter,
here is the code
Scaffold(
backgroundColor: kDarkTheme,
body: SafeArea(
child: Column(
children: [
const SizedBox(height: 10),
Row(
//code for top button
),
const SizedBox(height: 150),
Stack(
children: [
Center(
child: CircleAvatar(
radius: radiusSize + 5,
backgroundColor: kDarkCounterColor,
child: CircleAvatar(
backgroundColor: kDarkTheme,
radius: radiusSize,
),
),
),
Center(
child: Padding(
padding: const EdgeInsets.only(top: 35),
child: Text(
'39',
style: GoogleFonts.italiana(
fontSize: 120, color: kDarkCounterColor),
),
),
),
],
),
const SizedBox(height: 15),
const Text(
'Tap To Count',
style: TextStyle(
fontFamily: 'Helvatica',
color: Color(0xff656158),
),
),
Expanded(
child: Align(
alignment: Alignment.bottomRight,
child: SvgPicture.asset(
kDarkThemeImage,
)),
)
],
),
))
this is the code
then the first error appears again. how could I fix this?
You are using the Expanded widget on a column that doesn't have a set size. Try adding MainAxisSize attribute to your column, like this:
Column(
mainAxisSize: MainAxisSize.max, // Add this like
children: [
...
This will make your column fit the whole available size on the previous widget (a scaffold for the whole screen). Then the expanded widget will fill the remaining space not used by the other widgets inside the column.

Centered Text inside a button with an icon in Flutter

I'm having issues where I want to make a button (any kind to achieve this) that has an icon that is always in the same position at the start of the button, and that the text of the button is always centered compared to the text below it and always centered in the button itself, even if the text is dynamic. This is what I want to achieve:
The button text is centered according to the text below(that stays the same) and it is centered with the above button, but if the button text changes dynamically, then I have these issues:
Or like this one:
Any ideas how to solve this problem?
I tried with the Expanded widget and adding the flex properties but failed. I tried some other stuff too but failed also... Here is the button code:
TextButton(
style: ButtonStyle(
backgroundColor:
MaterialStateProperty.all(Colors.blue)),
onPressed: () {},
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Expanded(
flex: 1,
child: Icon(
Icons.keyboard_arrow_right_sharp,
color: Colors.white,
),
),
Expanded(
flex: 4,
child: Center(
child: Text(
"SOME TEXT",
style: TextStyle(color: Colors.white),
),
),
)
],
),
),
Thanks in advance for your help!
There are a couple of options to do that. I'm going to assume the size of the text could change so you want a flexible solution.
The first option is the most obvious of the two, but will break if the text is too long. The trick is to add an empty sizedBox at the end of the button, so the text can be centered in an expanded widget.
TextButton(
style: ButtonStyle(
backgroundColor: MaterialStateProperty.all(Colors.blue),
),
onPressed: () {},
child: Row(
children: [
Icon(
Icons.keyboard_arrow_right_sharp,
color: Colors.white,
size: 24,
),
Expanded(
child: Center(
child: Text(
"SOME TEXT",
style: TextStyle(
color:Colors.white,
),
),
),
),
SizedBox(
width: 24, // width of the icon
),
],
),
);
The other option is using a stack widget. This way, if the text is too long it will overlap with the icon but it's less probable that it will overflow the button.
TextButton(
style: ButtonStyle(
backgroundColor: MaterialStateProperty.all(Colors.blue),
),
onPressed: () {},
child: Stack(
children: [
Positioned(
left: 0,
child: Icon(
Icons.keyboard_arrow_right_sharp,
color: Colors.white,
size: 24,
),
),
Center(
child: Text(
"SOME TEXT",
style: TextStyle(
color:Colors.white,
),
),
),
],
),
);
Let's discuss about you code :
using row with a mainaxisalignment from start make the element start from the available area. then i suggest to use the SizedBox to make some of spacing between the elements as you want and play with the width of it.
TextButton(
style: ButtonStyle(
backgroundColor:
MaterialStateProperty.all(Colors.blue)),
onPressed: () {},
child: Row(
mainAxisAlignment: MainAxisAlignment.start, // here the issue
children: [
Expanded(
flex: 1,
child: Icon(
Icons.keyboard_arrow_right_sharp,
color: Colors.white,
),
),
SizedBox(width: MediaQuery.of(context).size.width * 0.08, // change this value as you want 0.08 or 0.1 ...etc
),
Expanded(
flex: 4,
child: Center(
child: Text(
"SOME TEXT",
style: TextStyle(color: Colors.white),
),
),
)
],
),
),
for more read this documentation

How can I change the width of a container/card depending on screen size?

I tried adding a width to the container but it didn't do anything. By default it fills the page? Not sure what's happening. Do I have to use MediaQuery somewhere? I want the post to be the same size on both the phone and the tablet. I'm not great with explaining so I added a photo to help.
Here's my code:
body: ListView(
children: [
Container(
height: 132,
decoration: BoxDecoration(borderRadius: BorderRadius.circular(15)),
child: Card(
margin: EdgeInsets.all(10),
elevation: 8,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(15)),
child: Column(
children: <Widget>[
ListTile(
leading: CircleAvatar(
backgroundColor: Color(0xFF192A4F),
),
title: SizedBox(
height: 39,
child: TextButton(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
AutoSizeText(
'Username',
style: TextStyle(
color: Color(0xFF192A4F),
fontSize: 16,
fontWeight: FontWeight.bold),
maxLines: 2,
overflow: TextOverflow.ellipsis,
),
],
),
style: TextButton.styleFrom(
padding: EdgeInsets.zero,
minimumSize: Size(50, 30),
alignment: Alignment.centerLeft),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => SeventhRoute(),
),
);
},
),
),
),
Divider(
height: 10,
color: Colors.black26,
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
Row(
children: <Widget>[
Icon(Icons.comment_outlined,
color: Colors.black),
SizedBox(width: 8.0),
Text(
'Comment',
style: TextStyle(color: Colors.black),
),
],
),
Row(
children: <Widget>[
Icon(Icons.bookmark_outline, color: Colors.black,),
SizedBox(width: 8.0),
Text('Bookmark', style: TextStyle(color: Colors.black),),
],
),
],
),
SizedBox(
height: 12.0,
)
],
),
),
),
],
),
double width = MediaQuery.of(context).size.width;
you can get screen width from here. Then add a logic
As example if screen width of right phone is 500 and left is 1000,
then you can set
if the screen width is <= 500 ,
set the container width as screen width
otherwise
set the container width as 500.
---Additionally---
You can get screen orientation like this
var isPortrait = MediaQuery.of(context).orientation == Orientation.portrait
The reason specifying the width is ignored is because you didn't specify what should happen with the smaller card. The framework doesn't know if it should be aligned left, center, right, etc. To fix this, you can wrap your Card, Container, or even the whole ListView in a Center (or Align) widget.
Based on your images i can see that only the width is changing, height is constant, so i'd suggest in your container give width: MediaQuery.of(context).size.width;
And of course some padding to that container.
It looks like you want that widget to take as much width as it can, but no more than 500px wide. Trivial:
ConstrainedBox(
child: YourChild(...),
constraints: BoxConstraints(maxWidth: 500),
),

Flutter: How to have Container/Column with fix height

The layout have uses column with Text and Image. The data change based from a list and some text/image are nil. How to make the container takes the same height when only one data is present?
Thanks.
body: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
Container(
color: Colors.red,
child: Column(
children: [
Text(
'This is Container/Column1. It have two widgets, Text and Image. How to make the height of the container same even if one the the widget is removed/null?',
),
Image.asset('assets/index.jpg')
],
),
),
Container(
color: Colors.green,
child: Column(
children: [
Text('This is Container/Column2. This will have additional widgets.'),
SizedBox(
width: double.maxFinite,
child: TextButton(
onPressed: () {},
style: TextButton.styleFrom(
backgroundColor: Colors.white,
),
child: Text('Next Button',
),),),],),),],),
first approach: add a fixed height to your container
Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
Container(
// this will give the container a fixed height of 0.4 from the screen height
height: MediaQuery.of(context).size.height * 0.4,
color: Colors.red,
child: Column(
children: [
Text(
'This is Container/Column1. It have two widgets, Text and Image. How to make the height of the container same even if one the the widget is removed/null?',
),
Image.asset('assets/index.jpg')
],
),
),
Container(
color: Colors.green,
child: Column(
children: [
Text('This is Container/Column2. This will have additional widgets.'),
SizedBox(
width: double.maxFinite,
child: TextButton(
onPressed: () {},
style: TextButton.styleFrom(
backgroundColor: Colors.white,
),
child: Text(
'Next Button',
),
),
),
],
),
),
],
),
second approach: if one of them is null add a SizedBox() with your prefered height
Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
Container(
height: MediaQuery.of(context).size.height * 0.4,
color: Colors.red,
child: Column(
children: [
someCondition ? Text(
'This is Container/Column1. It have two widgets, Text and Image. How to make the height of the container same even if one the the widget is removed/null?',
) : SizedBox(height : 40)
someCondition ? Image.asset('assets/index.jpg') : SizedBox(height : 40)
],
),
),
Container(
color: Colors.green,
child: Column(
children: [
Text('This is Container/Column2. This will have additional widgets.'),
SizedBox(
width: double.maxFinite,
child: TextButton(
onPressed: () {},
style: TextButton.styleFrom(
backgroundColor: Colors.white,
),
child: Text(
'Next Button',
),
),
),
],
),
),
],
);
One way is to wrap column with Expanded. Second is to have fixed height for contained. If you have this problem with ListView inside another widget and have problems, use shrinkWrap as true inside a ListView. And again for your problem (which person above failed to understand) is that you need or fixed value for height or use Expanded (as much space as possible) or Flexible (least space possible).