Flutter column with elements aligning to different sides without stretching the width of the column - flutter

I'd like to have a column take the width of the content, and have some elements align to right and some to the left.
Is this possible?
If I use Align widget on the children the whole column stretches in width. Is there another way?
Thank you
Edit: Example
Center(
child: Container(
color: Colors.yellow,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
color: Colors.red,
width: 50,
height: 50,
),
Text('Here goes some text with variable length'),
Container(
color: Colors.blue,
width: 50,
height: 50,
),
],
),
),
);
I want the column above with the red square to the left and the blue to the right (and the column not stretching to the available width).

Try this-
Center(
child: Container(
color: Colors.yellow,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Container(
color: Colors.red,
width: 50,
height: 50,
),
],
),
SizedBox(width: 100),
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
Container(
color: Colors.blue,
width: 50,
height: 50,
),
],
),
],
),
),
)

You can simply try to put the contents of the column in a row, so you would have elements inside containers for their width and height as you like.
Column -> Row -> aligned containers.

Related

How to center one element and place the second element next to it

In my layout I have two Widgets in a row, a text and a button.
How can I achieve something like below, where only the Text is centered, and the icon is simply next to it?
---------------------------
Text *
---------------------------
Using Row would center all the contents and would output something like
---------------------------
Text *
---------------------------
Tried: Row(children:[widget1, widget2], mainAxisAlignment: MainAxisAlignment.center);
But this centers both items, causing the text to look off-centered.
You can use CompositedTransformTarget and CompositedTransformFollower as mentioned on comment section by pskink.
class AppPT extends StatelessWidget {
const AppPT({super.key});
#override
Widget build(BuildContext context) {
final LayerLink _layerLink = LayerLink();
return Scaffold(
body: Column(
children: [
Stack(
children: [
Align(
child: CompositedTransformTarget(
link: _layerLink,
child: Container(
color: Colors.red,
width: 100,
height: 60,
alignment: Alignment.center,
child: Text("btn"),
),
),
),
CompositedTransformFollower(
link: _layerLink,
targetAnchor: Alignment.centerRight,
followerAnchor: Alignment.centerLeft,
child: Container(
color: Colors.cyanAccent,
width: 12,
height: 12,
alignment: Alignment.center,
child: Text("*"),
),
),
],
)
],
),
);
}
}
There are few tricks I can think of,
You can use Stack widget with Position.
including another widget on right by applying opacity(invisible) on current snippet.
using transform will be handle if you know the width of the widget.
Transform.translate(
offset: Offset(20 / 2, 0), //20 is the * box size
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
color: Colors.red,
width: 100,
height: 60,
alignment: Alignment.center,
child: Text("btn"),
),
Container(
color: Colors.green,
width: 20,
height: 20,
child: Center(child: Text("*")),
),
],
),
),
Place text and second widget inside row then put the row inside container with alignment center and use SizedBox for spacing between widget instead of Padding Widget.
Container(
color: Colors.green,
alignment: Alignment.center,
height: 100,
child: Row(
mainAxisSize: MainAxisSize.min,
children: const [
Text("Text"),
SizedBox(width: 10),
Text("*"),
],
),
);

Arrange Elements In Row At Start And Center

I have a dilemma that I can't seem to solve. I have an existing row in Flutter. Essentially what I want to accomplish is to have the first element(yellow) at the start of the row, and the second element(red) in the center of the element. I know Row has the mainAxisAlignment, but I need a different alignment for each each element (i.e. both MainAxisAlignment.start & MainAxisAlignment.center). Thanks for any help!
The closest I have been able to come to this is this:
Row(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
yellowElement,
Expanded(child: redElement),
],
);
But this is not perfectly centered, it is centered in the available space left over after yellow has taken its space.
I had this problem few weeks ago and the only solution I found was Stack... like this
Stack(
children: <Widget>[
Container(
color: Colors.grey,
width: 250,
height: 50,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
Container(width: 50, color: Colors.red),
],
),
),
Positioned(
top: 0,
bottom: 0,
child: Container(
width: 20,
color: Colors.yellow,
),
)
],
)

Control height of Column within Row

Trying to get the Column within the Row to take the full height of the Row (as seen in the image)
The Column takes the min height needed but surely there's a way to make it expand the full height of the Row widget? I tried using Expanded but that didn't work.
I want it to take the full height of the Row as then the elements within the Column can be alignment according to mainAxisAlignment: MainAxisAlignment.spaceBetween but at the moment as it takes the min height the elements are all be bunched up together.
return new Container(
child: ListView(
children: <Widget>[
Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Padding(
padding: EdgeInsets.all(20),
child: Text(
client.days[0].dayofLog,
style: TextStyle(
fontSize: 35,
color: Colors.black,
fontWeight: FontWeight.bold),
)),
Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
new AnimatedCircularChart(
key: _chartKey,
size: const Size(300.0, 300.0),
initialChartData: buildGraphElements(client),
chartType: CircularChartType.Radial,
edgeStyle: SegmentEdgeStyle.round,
percentageValues: true,
),
Expanded(
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
new Container(
height: 42.0,
width: 42.0,
color: Colors.red,
),
new Container(
height: 42.0,
width: 42.0,
color: Colors.red,
),
new Container(
height: 42.0,
width: 42.0,
color: Colors.red,
),
new Container(
height: 42.0,
width: 42.0,
color: Colors.red,
),
],
)
)
],
)
],
)
],
));
row size image
expanded size image
Try using:
final screenWidth = MediaQuery.of(context).size.width;
final screenHeight = MediaQuery.of(context).size.height;
and at the time of assigning them to your variables you can multiply them by the% of screen you create as necessary.
If possible post a photo with the expected result.

Word-wrapping do not working with long text

Here is my widget:
return Card(
child: Container(
height: 150,
child: Row(
children: <Widget>[
Placeholder(
fallbackHeight: 100,
fallbackWidth: 100,
),
Container(
width: _deviceHeight,
color: Colors.red,
child: Column(
mainAxisSize: MainAxisSize.max,
children: <Widget>[
Flexible(
child: Text(
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaasssssaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
overflow: TextOverflow.ellipsis,
maxLines: 4,
)),
// Expanded(flex: 8, child: Text("bbb")),
Flexible(child: Text("bbb")),
// Flexible(child: Text("aaa")),
],
),
)
],
),
));
I expected that text will be placed on new line, but I am getting overflow:
Wrap your inner Container with an Expanded to provide it with the available parent constraints, otherwise the Container has infinite height and will result in an overflow (because you are on landscape).
Expanded(
child: Container(
width: _deviceHeight,
color: Colors.red,
child: Column(
...
You could wrap the second element of the Row with Flexible, like this:
Row(
children: <Widget>[
Placeholder(..),
Flexible(
child: Container(
color: Colors.red,
child: Column(...
Inside the Row you need Placeholder to keep its width and Container width to be flexible.
Edit: And you should remove the width of the Container, since it would be flexible and it should take as much as possible to fit the screen.

Flutter - How create Container with width match parent?

I use this simple widget in my Flutter app:
FlatButton(
child: Column(
children: <Widget>[
Image.asset(assets, height: 40, width: 40),
Text('Title'),
//my color line
Container(
height: 5,
width: ?,
color: Colors.blue[800],
)
],
)
)
I need color line (in buttom), with width match parent. but I don’t know how to do it.
Container(
height: 5,
width: double.infinity,
color: Colors.blue[800],
)
Use IntrinsicWidth
FlatButton(
child: IntrinsicWidth(
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
Image.asset(assets, height: 40, width: 40),
Text('Title'),
//my color line
Container(
height: 5,
width: ?,
color: Colors.blue[800],
)
],
))
)
Some cheatsheet
Two ways of doing this
ConstrainedBox:
It Creates a widget that imposes additional constraints on its child, which internally uses SingleChildRenderObjectWidget to add constraints over the child widget.
ConstrainedBox(
constraints:
const BoxConstraints(minWidth: double.infinity, maxHeight: 10),
child: Container(
color: Colors.blue,
),
),
SizedBox:
SizedBox simply creates a box with a given width/height and doesn't allow the child to go beyond given dimensions. It also used SingleChildRenderObjectWidget to decide the child render area
SizedBox(
width: double.infinity,
height: 5,
// height: double.infinity,
child: Container(
color: Colors.blue,
),
),
Container in a Column with no child will always expand. if you do add a child it will wrap it.
Also if you don't constrain your Column in the button it will also grow to full available height.
My suggestion to you is instead of putting an empty Container in your button's Column, rather wrap the button with a Container and give it a bottom border. This will give you your colored line on the bottom.
Container(
decoration: BoxDecoration(
border: Border(
bottom: BorderSide(width: 5, color: Colors.blue[800]),
),
),
child: FlatButton(
onPressed: () {},
child: Column(
mainAxisSize: MainAxisSize.min, // prevent Column to expand full height
children: <Widget>[
Icon(Icons.cake, size: 40),
Text('title'),
],
),
),
),