Text width based on text length in flutter - flutter

I have this ListView.generator that returns such Containers
Container(
child: Row(
children: <Widget>[
Container(
child: null,
width: 10,
height: 10,
decoration: BoxDecoration(
color: social[i].color,
shape: BoxShape.circle,
),
margin: EdgeInsets.only(right: 7, top: 1,),
),
Text(
social[i].name,
style: TextStyle(
color: Colors.white,
fontFamily: 'Muli',
fontSize: 24.0,
fontWeight: FontWeight.w700
),
)
],
),
width: social[i].name.length * 16.0,
)
Right know I'm making use of width to set it based on text length but it's giving me and inadequate result as spacing between twitter and instagram is bigger than it should be.
The result I want being this with an even space between them.
A Wrap widget with spacing set to even wouldn't help as I want this list to have a full width of the user resolution and to be aligned to the left.

you can use mainAxisAlignment: MainAxisAlignment.spaceEvenly for Row element like
Container(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
Container(
child: null,
width: 10,
height: 10,
decoration: BoxDecoration(
color: social[i].color,
shape: BoxShape.circle,
),
margin: EdgeInsets.only(right: 7, top: 1,),
),
Text(
social[i].name,
style: TextStyle(
color: Colors.white,
fontFamily: 'Muli',
fontSize: 24.0,
fontWeight: FontWeight.w700
),
)
],
),
width: social[i].name.length * 16.0,
)
In case you want to know more about it. https://medium.com/jlouage/flutter-row-column-cheat-sheet-78c38d242041 you can check this article. I found it really helpful.

Related

How to set width after using row in Flutter?

In this code when I am not using row then proceed button is not expanding but when I am using Row for adding one more widget then that is expanding.
This is my code.
Stack(
alignment: Alignment.centerRight,
children: [
Container(
margin: EdgeInsets.all(5),
height: 150,
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage(
'assets/assets_allocation_image.png',
),
fit: BoxFit.fill)),
),
Column(
children: [
Text(
"Know your\nASSET ALLOCATION",
textAlign: TextAlign.center,
style: TextStyle(
color: Colors.white,
fontSize: tSize18,
fontWeight: FontWeight.w600),
overflow: TextOverflow.ellipsis,
maxLines: 2,
),
Padding(
padding: const EdgeInsets.only(
top: 20,
),
child: Container(
padding: const EdgeInsets.only(
left: 10, right: 10, top: 5, bottom: 5),
decoration: BoxDecoration(
color: orangeColor,
border: Border.all(
color: orangeColor, width: 2.0, style: BorderStyle.solid),
borderRadius: BorderRadius.all(
Radius.circular(3),
),
),
child: Row( // here
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
'Proceed',
style: TextStyle(
fontSize: tSize12,
fontWeight: FontWeight.w500,
color: whiteColor),
textAlign: TextAlign.center,
),
SizedBox(width: 3,),
Icon(
Icons.arrow_circle_right_outlined,
color: Colors.white,
size: 18,
)
],
),
),
),
],
),
],
);
This is my ui
I want UI like this
How to possible without wrapping in container and without giving width Becouse if I will give fix width then if user changed text size from mobile device then it will give me overflow error.
so how to fix it?
You can apply mainAxisSize and row will not expand anymore
Row(
mainAxisSize: MainAxisSize.min,
...
Container tries to expand to the available space. Since you are using Column as it's parent, there are no restrictions on width of the Container. Hence it expands to its full width.
One way you can achieve is by replacing the Container with DecoratedBox which has no size constraints and tries to fit to the width and height of its child widget. Use proper padding around the Text widget. That would be sufficient to achieve the above.
Also add mainAxisSize: MainAxisSize.min to Row widget.
Example code is as below. Please look at the code comment as well for the changes
Column(
children: [
Text(
"Know your\nASSET ALLOCATION",
textAlign: TextAlign.center,
style: TextStyle(
color: Colors.white,
fontSize: tSize18,
fontWeight: FontWeight.w600),
overflow: TextOverflow.ellipsis,
maxLines: 2,
),
child: DecoratedBox( // change Container to DecoratedBox
decoration: BoxDecoration(
color: orangeColor,
border: Border.all(
color: orangeColor, width: 2.0, style: BorderStyle.solid),
borderRadius: BorderRadius.all(
Radius.circular(3),
),
),
child: Padding(
padding: const EdgeInsets.symmetric(horizontal:24,vertical:16),//here change the value as per your requirement
child :Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
'Proceed',
style: TextStyle(
fontSize: tSize12,
fontWeight: FontWeight.w500,
color: whiteColor),
textAlign: TextAlign.center,
),
SizedBox(width: 3,),
Icon(
Icons.arrow_circle_right_outlined,
color: Colors.white,
size: 18,
)
],
),
),
),
],
)

TextWidthBasis.longestLine alternative for AutoSizeText?

For a single line of text I have
Center(
child: Container(
decoration: BoxDecoration(
border: Border(
bottom: BorderSide(
width: 1,
),
),
),
child: Text('Some text',
style: TextStyle(
fontSize: 60),
textAlign: TextAlign.center,
textWidthBasis: TextWidthBasis.longestLine,
),
),
),
Which works great. But when I use AutoSizeText for multiple lines of text I can't remove the padding with textWidthBasis: TextWidthBasis.longestLine so the underline goes fully across the screen.
Is there another way to remove the padding?
I've got two options for you, both of them are workarounds more than solutions to be honest, but sometimes in Flutter, that's the best you've got 😩
(2 is a lot better than 1, good luck! happy coding!)
1.
First is giving the original container a small padding as to not disrupt the text much:
Padding(
padding: const EdgeInsets.symmetric(horizontal: 8.0),
child: Container(
decoration: BoxDecoration(
border: Border(
bottom: BorderSide(
width: 1,
),
),
),
child: AutoSizeText('Some text\ndummy text\n some texttttttt',
style: TextStyle(
fontSize: 60),
textAlign: TextAlign.center,
),
),
),
Which gives this output: https://gyazo.com/0c9d343ba6843d61327f2a33893fc81d
2.
You can wrap the container with a Column and simply but a divider underneath it as so (keep in mind that "indent" and "endIndent" controlles the right/left "padding" of the divider!):
Column(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
child: AutoSizeText(
'Some text\ndummy text\n some texttttttt',
style: TextStyle(fontSize: 60),
textAlign: TextAlign.center,
),
),
Divider(height: 1, thickness: 1, color: Colors.black, indent: 40, endIndent: 40,)
],
),
Which gives this output: https://gyazo.com/b7cefe2b36442939e13ecf344a858f31

How to stretch Containers inside Row to maximum available height?

I have a Row widget, which has many containers with different heights depending on their content. I want to have an equal height of them all. How can I achieve this without hardcoding their values?
This is something I have.
But I want the first card to take the height of the row automatically. So that both cards would be of the same height. How can I achieve this?
This is the code for Card Container:
Widget build(BuildContext context) {
final statusMap = statusOptionView();
return Container(
width: 200,
margin: EdgeInsets.only(right: 20.0),
child: Stack(
children: <Widget>[
Container(
padding: EdgeInsets.only(
left: 20.0, right: 20.0, top: 20.0, bottom: 50.0),
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(20.0)),
color: Color(0xFFF97F8B),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Row(
children: <Widget>[
Icon(
Icons.access_time,
color: Colors.white,
),
SizedBox(width: 4.0),
Text(
event.startTime,
style: TextStyle(
color: Colors.white,
),
)
],
),
SizedBox(
height: 20.0,
),
Text(
event.title,
style: TextStyle(
fontWeight: FontWeight.w600,
fontSize: 20.0,
color: Colors.white,
),
maxLines: 2,
),
SizedBox(
height: 20.0,
),
Row(
children: <Widget>[
Icon(
Icons.location_on,
color: Colors.white,
),
SizedBox(
width: 4.0,
),
Expanded(
child: Text(
event.venue,
style: TextStyle(
color: Colors.white,
),
maxLines: 1,
overflow: TextOverflow.ellipsis,
),
)
],
),
],
),
),
Positioned(
bottom: 0.0,
right: 0.0,
left: 0.0,
child: GestureDetector(
onTap: () => Navigator.push(context, MaterialPageRoute(
builder: (BuildContext context) => EventDetailsScreen(event: event, status: status))),
child: Container(
padding: EdgeInsets.symmetric(vertical: 8.0),
decoration: BoxDecoration(
color: Colors.purple,
borderRadius: BorderRadius.circular(30.0)),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Icon(
statusMap['icon'],
color: Colors.white,
size: 16.0,
),
SizedBox(
width: 10.0,
),
Text(
statusMap['value'],
style: TextStyle(
color: Colors.white,
),
),
],
),
),
),
)
],
),
);
While it is wrapped inside a Row widget, just like this:
Row(
children: <Widget>[...events.map((event) => EventCard(event: event)).toList()],
)
Use IntrinsicHeight as parent of Row that contains Card
You can use CrossAxisAlignment.stretch to make all children of a Row/Column use the same height/width.
/// Require the children to fill the cross axis.
///
/// This causes the constraints passed to the children to be tight in the
/// cross axis.
stretch,
Check out https://codepen.io/kuhnroyal/pen/wvGormg
In your case, row is a child of column and column gives full available height to its children so row as a child of the column, take full available height so to tell column that only give required height to its children try to give MainAxisSize.min property to Column. I am not sure it works or not but you can try.
Row(
mainAxisAlignment : MainAxisAlignment.spaceEvenly,
.....)
or try wrapping every widget with expanded.
Hoping that it works

Flutter infinite width exception

I want to align my transaction title and date to the left but when I give the parent container the full width of the row i.e. double.infinity, the following exception is thrown "BoxConstraints forces an infinite width". What could be the possible reason?
body: new Column(
mainAxisAlignment: MainAxisAlignment.spaceAround,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
new Card(child: new Text("CHART!")),
new Column(
children: [
...transactions.map((transaction) {
return new Card(
child: new Row(
children: [
new Container(
padding: EdgeInsets.all(10),
decoration: new BoxDecoration(
border: Border.all(
color: Colors.purple,
width: 2,
),
),
margin: EdgeInsets.symmetric(
vertical: 10,
horizontal: 15,
),
child: new Text(
transaction.amount.toString(),
style: new TextStyle(
fontWeight: FontWeight.bold,
fontSize: 20,
color: Colors.purple),
),
),
new Column(
children: [
new Container(
width: double.infinity,
child: new Text(
transaction.title,
style: new TextStyle(
fontWeight: FontWeight.bold, fontSize: 17),
),
),
new Container(
child: new Text(
transaction.date.toString(),
style: new TextStyle(color: Colors.grey),
),
),
],
)
],
),
);
})
],);
The Row() widget does not have a width property, meaning that you should put the Row() inside another Container(), so that the row knows what its constraints are, like this:
new Row(
children: [
new Container(
padding: EdgeInsets.all(10),
decoration: new BoxDecoration(
border: Border.all(
color: Colors.purple,
width: 2,
),
),
margin: EdgeInsets.symmetric(
vertical: 10,
horizontal: 15,
),
child: new Text(
transaction.amount.toString(),
style: new TextStyle(
fontWeight: FontWeight.bold,
fontSize: 20,
color: Colors.purple),
),
),
new Column(
children: [
new Container(
width: MediaQuery.of(context).size.width,,
child: new Text(
transaction.title,
style: new TextStyle(
fontWeight: FontWeight.bold, fontSize: 17),
),
),
new Container(
child: new Text(
transaction.date.toString(),
style: new TextStyle(color: Colors.grey),
),
),
],
)
],
Note: the new keyword is optional. Furthermore, setting a width to infinity will only cause problems, since it will always go out of the screen, creating an overflow.
The problem is You are setting stretch for crossAxisAlignment, which gives infinite width to the column. You can provide constraint to the Container, through width property by setting
width: MediaQuery.of(context).size.width
This should work.

Flutter : How can i create this circle avatar that's half out of the container?

How can I create this design I found in pinterest
I just wanted to create the user circle half of the container I tried many ways but failed.
Thanks.
To let that half circle get out of the box you need to add some padding on top of the Container to make room for what you desire. Here's a sample code. first define the size of the circle container. here I named it "circleRadius" :
final double circleRadius = 120.0;
Container(
height: double.infinity,
width: double.infinity,
color: Color(0xffE0E0E0),
child: Stack(children: <Widget>[
Padding(
padding: const EdgeInsets.all(16.0),
child: Stack(
alignment: Alignment.topCenter,
children: <Widget>[
Padding(
padding:
EdgeInsets.only(top: circleRadius / 2.0, ), ///here we create space for the circle avatar to get ut of the box
child: Container(
height: 300.0,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(15.0),
color: Colors.white,
boxShadow: [
BoxShadow(
color: Colors.black26,
blurRadius: 8.0,
offset: Offset(0.0, 5.0),
),
],
),
width: double.infinity,
child: Padding(
padding: const EdgeInsets.only(top: 15.0, bottom: 15.0),
child: Column(
children: <Widget>[
SizedBox(height: circleRadius/2,),
Text('Maria Elliot', style: TextStyle(fontWeight: FontWeight.bold, fontSize: 34.0),),
Text('Albany, NewYork', style: TextStyle(fontWeight: FontWeight.bold, fontSize: 16.0, color: Colors.lightBlueAccent),),
SizedBox(
height: 30.0,
),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 32.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Column(
children: <Widget>[
Text('Likes', style: TextStyle( fontSize: 20.0, color: Colors.black54,),),
Text('12K', style: TextStyle( fontSize: 34.0, color: Colors.black87, fontFamily: ''),),
],
),
Column(
children: <Widget>[
Text('Wished', style: TextStyle( fontSize: 20.0, color: Colors.black54),),
Text('12K', style: TextStyle( fontSize: 34.0, color: Colors.black87, fontFamily: ''),),
],
),
Column(
children: <Widget>[
Text('Purchased', style: TextStyle( fontSize: 20.0, color: Colors.black54),),
Text('12K', style: TextStyle( fontSize: 34.0, color: Colors.black87, fontFamily: ''),),
],
),
],
),
)
],
)
),
),
),
///Image Avatar
Container(
width: circleRadius,
height: circleRadius,
decoration: BoxDecoration(
shape: BoxShape.circle,
color: Colors.white,
boxShadow: [
BoxShadow(
color: Colors.black26,
blurRadius: 8.0,
offset: Offset(0.0, 5.0),
),
],
),
child: Padding(
padding: EdgeInsets.all(4.0),
child: Center(
child: Container(
child: Icon(Icons.person), /// replace your image with the Icon
),
),
),
),
],
),
),
]),
),
and the output:
You can use a ClipOval with the Image for the Circle
Then to get it in the half of the container use the Stack widget combined with the Positioned Widget
Example:
Stack(
children: <Widget>[
Container(
width: 250,
height: 250,
color: Colors.red,
),
Positioned(
top:50 ,//change this as needed
child:ClipOval(
child: Image.network(
'https://picsum.photos/250?image=9',
),
),
),
],
),
References
Network Image
ClipOval
Great Tutorial
Stack
Positioned