I have one "row" and two "text" widgets inside. I want to align the starting place of two texts. ie "m. name" and "m105" should line up.
Container(
child: Row(
children: [
Container(
child: Align(
alignment: Alignment.topLeft,
child: Text(
"M. Adı: ",
style: TextStyle(fontWeight: FontWeight.bold),
),
),
),
// SizedBox(
// width: 20,
// ),
Expanded(
child: Text(
"$productName",
overflow: TextOverflow.ellipsis,
maxLines: 3,
softWrap: true,
),
),
],
),
),
Try
Row() widget attribute
crossAxisAlignment: CrossAxisAlignment.start
Text() widget attribute
textAlign: TextAlign.start,
/// Try something like that
Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
"M. Adı: ",
style: TextStyle(fontWeight: FontWeight.bold),
),
),
SizedBox(width: 5),
Flexible(
child: Text(
"$productName",
textAlign: TextAlign.start,
),
),
],
),
Add crossAxisAlignment: CrossAxisAlignment.center, to your Row widget it should be aligned as you desired or still if it doesnt works just try changing center with other values check which one works for you...
and even after adding above property to your Row widget then you would have to remove alignment of topleft in your text of m.name
Related
I'm trying to make a menu for a reastaurant like this one : -
I'm using Flutter and this is my code:
return Column(
mainAxisSize: MainAxisSize.min,
children: [
ListTile(
title: Row(
children: [
Expanded(child: Text( text, style: style, )),
const SizedBox( width: 15 ),
Text( '\$ $price', style: style,),
],
),
),
Divider( color: Colors.white.withOpacity( 0.5 ),),
],
);
But this is the result that I'm getting : -
Please, any help will be welcome.
And thanks in advance.
The result that you want to achieve can be done just by using the row widget, you don't have to wrap it up with ListTile. I am writing the code snippet of Row widget for you. You can copy paste it and it will work. Additionally I see that you are generating it in the column widget. If you have a dynamic array then I suggest that you use ListView Divider instead. It will have a divider to add between your rows as well. You can find more about it on flutter official documentation.
Row(
children:[
//You may add some padding to Text for better looking UI.
Text("Chicken Masala"),
Expanded(child:Divider()),
Text("180")
])
Just replace your column's children with this row and you will be able to see it.
I solved your issue like this:
Output of your issue : -
body: Column(
mainAxisSize: MainAxisSize.min,
children: [
ListTile(
title: Row(
children: [
const Text(
'Cheese Burger',
),
Expanded(child: Text('.' * 100, maxLines: 1)),
const Text(
'\$ 10',
),
],
),
),
const SizedBox(
height: 10,
),
ListTile(
title: Row(
children: [
const Text(
'Chicken Masala Soup',
),
Expanded(child: Text('.' * 100, maxLines: 1)),
const Text(
'\$ 10',
),
],
),
),
],
),
#Ramji, #Dhruvil Patel, I try your code and it work fine, but it was making an overflow when the text was long, so I made some changes in your example and I got what I was looking for.
Thanks a lot for you help.
Here is what I dit.
return SizedBox(
width: double.infinity,
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Row(
children: [
Expanded( child: Text( text, style: style, maxLines: 2, overflow: TextOverflow.ellipsis, ) ),
],),
Row(
children: [
Expanded(
child: Text(
'.' * 150,
style: style,
maxLines: 1,
overflow: TextOverflow.fade,)),
SizedBox(
width: 80,
child: Text(
'\$ $price',
style: style,
textAlign: TextAlign.right,)),
],
),
// Divider( color: Colors.white.withOpacity( 0.5 ),),
],
),
);
I am trying to align the name to the left side but it is not working. Always displays in the center suppose I use text-align. So, How to resolve this issue?
Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
"Name",
maxLines: 1,
overflow: TextOverflow.ellipsis,
softWrap: false,
textAlign: TextAlign.left,
style: const TextStyle(fontSize: 16,color: Colors.black,fontWeight: FontWeight.bold,),
),
const SizedBox( width: 160,
child:Text(
"mynameee#gmail.com",
maxLines: 3,
overflow: TextOverflow.ellipsis,
softWrap: true,
style: const TextStyle(
fontSize: 12,
color: Colors.black,
),
),),
],
),
In column widget add this line :
crossAxisAlignment: CrossAxisAlignment.start
and remove :
mainAxisAlignment: MainAxisAlignment.center,
Add this to column:
crossAxisAlignment: CrossAxisAlignment.start,
Warp your column with Container and then inside the container enter below line:
alignment:Alignment.center
add Container for the text and give it alignment
Like this:
Container(
alignment: Alignment.centerLeft,
child:Text('text here')
)
And you want display the name and email together use Row
Like this:
Row(
mainAxisAlignment: MainAxisAlignment.start,
children:[
Text("name:"),
Text("Example#gmail.com"),
]
)
And the output well be like this:
Name: Example#gmail.com
Container(
alignment: Alignment.centerLeft,
child:Text('text here',textalign:center)
)
That's how it looks when I have a WidgetSpan and a TextSpan, and the text inside the TextSpan is too long:
problem
A similar question has already been asked here TextSpan's text doesn't show if it overflows and is placed after WidgetSpan, but the one answer isn't suitable for my problem.
I have two Text.rich() widgets (which each host one WidgetSpan and one TextSpan) inside an Expanded widget, both Expanded with flex:1, because I want them to be the same size and take as much space as they can. That's why a row is not an option, you can't (as far as I know) put two rows side by side, at this happens...
using rows
This is how it's supposed to look like, just with the TextOverflow.ellipsis, if the text is too long:
target UI
Here is my code:
Row(
children: [
Expanded(
flex: 1,
child: Text.rich(
TextSpan(children: [
WidgetSpan(
child: Container(
margin: const EdgeInsets.only(right: 4.0),
child: SvgPicture.asset("assets/icons/building.svg", color:
htLightGrey),
),
),
TextSpan(
text: incident.building.name,
style: const TextStyle(
fontWeight: FontWeight.normal,
fontSize: 16.0,
color: htLightGrey, /*overflow: TextOverflow.ellipsis*/
),
),
]),
maxLines: 1,
overflow: TextOverflow.ellipsis,
),
),
Expanded(
flex: 1,
child: incident.department != null
? Text.rich(
TextSpan(children: [
WidgetSpan(
child: Container(
margin: const EdgeInsets.only(right: 4.0),
child: SvgPicture.asset("assets/icons/department.svg",
color: htLightGrey),
),
),
TextSpan(
text: incident.department!.name,
style: const TextStyle(fontWeight: FontWeight.normal,
fontSize: 16.0, color: htLightGrey, overflow:
TextOverflow.ellipsis),
),
]),
maxLines: 1,
overflow: TextOverflow.ellipsis,
)
: const SizedBox.shrink(),
)
],
)
To achieve your target Ui, use the Wrap widget instead of the Row widget. Here, when the contents of the widget overflow/exceed it will break it to the next line, hence you'll achieve your target Ui.
While we like to archive this UI, we are using Row as parent widget, which is perfect. Then we can split the row into tree part, left two part will get same and maximum available width. For this scenario, widget structure as follows.
Row(
mainAxisSize: MainAxisSize.min,
children: [
Expanded(
flex: 1,
child: Container(
color: Colors.green,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start, //start from left
children: [
buildItem(
text:
"incident.buildi cident.buildi cident.buildi cident.buildi cident.building.name"),
buildItem(text: "incide ing.ssss"),
],
),
),
),
Expanded(
flex: 1,
child: Container(
color: Colors.red,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
buildItem(text: "i ent.building.name"),
buildItem(text: "incident.building.ssss"),
],
),
),
),
IconButton(
onPressed: () {},
iconSize: 33,
icon: Icon(Icons.arrow_right),
),
],
),
And inside Text.rich add use alignment: PlaceholderAlignment.middle, on WidgetSpan to set the middle.
maxLines: 1,
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.start,
And you will get
I am using extra container to point the UI, simply remove the container from the column. Also, you can use Row instead of Rich Text.
Test widget
class _TestGroundState extends State<TestGround> {
#override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
children: [
Row(
mainAxisSize: MainAxisSize.min,
children: [
Expanded(
flex: 1,
child: Container(
color: Colors.green,
child: Column(
crossAxisAlignment:
CrossAxisAlignment.start, //start from left
children: [
buildItem(
text:
"incident.buildi cident.buildi cident.buildi cident.buildi cident.building.name"),
buildItem(text: "incide ing.ssss"),
],
),
),
),
Expanded(
flex: 1,
child: Container(
color: Colors.red,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
buildItem(text: "i ent.building.name"),
buildItem(text: "incident.building.ssss"),
],
),
),
),
IconButton(
onPressed: () {},
iconSize: 33,
icon: Icon(Icons.arrow_right),
),
],
),
],
));
}
Text buildItem({
required String text,
}) {
return Text.rich(
TextSpan(
children: [
WidgetSpan(
alignment: PlaceholderAlignment.middle,
child: Container(
child: Icon(Icons.ac_unit),
),
),
TextSpan(
text: text,
style: TextStyle(
fontWeight: FontWeight.normal,
fontSize: 16.0,
),
),
],
),
maxLines: 1,
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.start,
);
}
}
More about flutter layout
I have a Row of 3 text widgets. I want the first two to stay together and the third one to be aligned at the end of the row. The first text has the potential to cause an overflow, and when that happens, I only want the first text to be clipped by an ellipsis. Note that the 2nd and 3rd text can vary in length too, so the width at which clipping should be done varies.
I have tried various things, with RichText, Spacer, Expanded, Flexible, etc. The closest I have come to a solution is with this:
Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Flexible(
child: Text(
"Left most text that overflows the screen and creates an ellipsis",
overflow: TextOverflow.ellipsis,
),
),
Text(
"Xyz",
style: customStyle1,
),
Text(
" 10:20",
style: customStyle2,
),
],
),
This is what it leads to (with added colors). If the time stays to the right in the first row, the problem will be solved.
Adding a spacer between the last two texts causes the first to occupy just half the screen, i.e., the ellipsis gets added prematurely. Adding an Expanded to last Text causes the
"NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE" bug.
The first and the last row in this image are the desired outputs.
How do I accomplish this? And can anyone explain the issue with using a Spacer or an Expanded as mentioned above?
We can use two rows to align items, Flexible and Text softWrap to fix the overflow
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Expanded(
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
children: const [
Flexible(
child: Text(
"Left most text that overflows the screen and creates an ellipsis",
overflow: TextOverflow.ellipsis,
softWrap: false,
),
),
Text("Xyz"),
],
),
),
Text(
" 10:20",
),
],
),
You can use a constrained box
Row(
children: [
ConstrainedBox(
constraints: BoxConstraints(
maxWidth: MediaQuery.of(context).size.width / 2,
),
child: const Text(
"Left most text that overflows the screen and creates an ellipsis",
overflow: TextOverflow.ellipsis,
),
),
const Text('xyz'),
const Spacer(),
const Text('10:20'),
],
),
///you can use SizedBox and assign width and you can set your text. This is not the perfect solution but this works for me.
import 'package:flutter/material.dart';
class MyAseet extends StatefulWidget {
const MyAseet({Key? key}) : super(key: key);
#override
_MyAseetState createState() => _MyAseetState();
}
class _MyAseetState extends State<MyAseet> {
#override
Widget build(BuildContext context) {
return Scaffold(
body: Padding(
padding: const EdgeInsets.only(left:20.0,top: 50),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.start,
children: [
SizedBox(
width: 200,
child: Text(
"Left most text that overflows the screen and creates an ellipsis",
overflow: TextOverflow.ellipsis,
maxLines: 1,
),
),
Text(
"Xyz",
style: TextStyle(color: Colors.grey),
),
Container(
color: Colors.blue,
child: Text(
" 10:20",
),
),
],
),
Row(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.start,
children: [
SizedBox(
width: 200,
child: Text(
"Left most text that overflows the screen and creates an ellipsis",
overflow: TextOverflow.ellipsis,
maxLines: 1,
),
),
Text(
"Xyz",
style: TextStyle(color: Colors.grey),
),
Container(
color: Colors.blue,
child: Text(
" 10:20",
),
),
],
),
],
),
),
);
}
}
So, I want the row with a string of 2 lines ("Some long string with 2 lines heres") to be properly aligned with the string of 1 line: ("Name:"), but I want to do this WITHOUT checking the string length.
This is my code for the row:
Row(
children: <Widget>[
Text(
title,
style: Theme.of(context).textTheme.headline6.copyWith(height: 1.24),
),
Spacer(),
Container(
width: 242.0,
alignment: Alignment.bottomRight,
child: Text(
text,
textAlign: TextAlign.end,
maxLines: 2,
style: Theme.of(context).textTheme.bodyText1.apply(
color: kGrey,
),
),
),
],
);
As for the result I want, here's an image example:
Use crossAxisAlignment Row parameter to align the text to start crossAxisAlignment: CrossAxisAlignment.start
Solution-
Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
title,
style: Theme.of(context)
.textTheme
.headline6
.copyWith(height: 1.24),
),
Spacer(),
Container(
width: 242.0,
alignment: Alignment.bottomRight,
child: Text(
text,
textAlign: TextAlign.end,
maxLines: 2,
style: Theme.of(context).textTheme.bodyText1.apply(
color: kGrey,
),
),
),
],
),
Hope this will help you If you have any doubts ask in comment.