I used a card widget in my flutter App that has two rows, the problem that I have is a large space appeared between the two rows as you can see in the following image
how can fix this problem ?
my code that i tried it here :
return Card(
child: Container(
alignment: FractionalOffset.center,
child: Row(
children: <Widget>[
Expanded(
flex: 1,
child: Container(
child: ListTile(
title: Text(snapshot.data[index].data["title"],
textDirection: TextDirection.rtl,
style: TextStyle(fontSize: 14.0,
fontFamily: 'Cairo',
fontWeight: FontWeight.bold),),
onTap: () => navigateToDetails(snapshot.data[index]),
),
),
),
//SizedBox(width: 1.0),
Expanded(
flex: 1,
child: Container(child: Image.network(snapshot.data[index].data["image_url"],height: 80.0,width: 80.0)),
),
],
),
),
);
add MainAxisAlignment:MainAxisAlignment.center property to your Row widget
followed code should work for you check this out.
return Card(
child: Container(
alignment: FractionalOffset.center,
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Expanded(
flex: 1,
child: Container(
child: ListTile(
title: Text(
snapshot.data[index].data["title"],
textDirection: TextDirection.rtl,
style: TextStyle(
fontSize: 14.0,
fontFamily: 'Cairo',
fontWeight: FontWeight.bold),
),
onTap: () => navigateToDetails(snapshot.data[index]),
),
),
),
//SizedBox(width: 1.0),
Expanded(
flex: 1,
child: Container(
child: Image.network(snapshot.data[index].data["image_url"],
height: 80.0, width: 80.0)),
),
],
),
),
);
you are using expanded widget inside row so that both the widget try to get same width and also try to cover whole width possible.
so that, if you want to remove space between row widget then remove expanded widget and play with MainAxisAlignment property of Row to arrange or manage the space.
you can use values like:
MainAxisAlignment.spaceBetween and MainAxisAlignment.spaceEvenly
Related
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
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.
I am unable to make my text stop extending the screen and overflowing. My code is as follows:
class OrderTileDisplay extends StatelessWidget {
final MenuOrderData orderItem;
final editable;
OrderTileDisplay(this.orderItem, {this.editable = true});
#override
Widget build(BuildContext context) {
return Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
GestureDetector(
onTap: (){},
child: Container(
color: Colors.transparent,
margin: EdgeInsets.symmetric(vertical: 4),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Row(
children: [
Text(
orderItem.quantity.toString() + 'x',
style: Title16,
),
SizedBox(
width: 8,
),
Text(
orderItem.name, // OVERFLOWS WHEN IT IS A LONGER SENTENCE
style: Title18bold,
overflow: TextOverflow.ellipsis,
),
],
),
Row(
children: [
editable? Icon(Icons.edit, color: Colors.grey[200], size: 20,) : Container(),
SizedBox(width: 8,),
Text("£" + Provider.of<CP>(context).getTotalForItem(orderItem).toStringAsFixed(2),
style: Title18bold,),
],
),
],
),
),
),
Container(... and other stuff)
I have tried putting Text inside a container then Expanded widget but I keep getting errors. Not sure how to solve it.
Try to wrap your Row and Text inside a Flexible:
Flexible( //flexible here
child: Row(
children: [
Text(
orderItem.quantity.toString() + 'x',
style: Title16,
),
SizedBox(
width: 8,
),
Flexible( //and here
child: Text(
orderItem.name, // no more overflow
style: Title18bold,
overflow: TextOverflow.ellipsis, //working as expected
),
),
],
),
),
As the documentation states, TextOverflow says how overflowing text should be handled, but it will not work if it's parent don't have a fixed size. In this case, Flexible is been used to restrict the total size of the text to prevent overflow, when it reaches a very large width.
I'm getting the problem when I add Scrolling functionality in Scaffold, here I have tried SingleChildScrollView, CustomerScrollView, and ListView but it freezes the UI but when I replaced ti Scaffold to LayoutBuilder it works but all the background my UI got black.
I just want to add scrolling functionally to Scaffold.
Widget build(BuildContext context) {
return WillPopScope(
onWillPop: () {
...Some Code...
},
child: Scaffold(
body: Column(
children: <Widget>[
Expanded(
flex: 3,
child: Container(
padding: EdgeInsets.all(15.0),
alignment: Alignment.bottomLeft,
child: Text(
mydata[0][i.toString()],
style: TextStyle(fontSize: 16.0, fontFamily: "Quando"),
),
)),
Expanded(
flex: 6,
child: Container(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
choiceButton('a'),
choiceButton('b'),
choiceButton('c'),
choiceButton('d'),
],
),
)),
Expanded(
flex: 1,
child: Container(
alignment: Alignment.topCenter,
child: Text(showtimer,
style: TextStyle(
fontSize: 35.0,
fontFamily: "Times New Roman",
fontWeight: FontWeight.w700)),
))
],
),
) // Scaffold
);// WillPopScope
}
Try This
return Scaffold(
resizeToAvoidBottomInset: false,
extendBodyBehindAppBar: false,
backgroundColor: Colors.white,
body: Column(
children: <Widget>[
Expanded(
child: SingleChildScrollView(
child: Container(
height: MediaQuery.of(context).size.height,
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
],
),
),
),
),
]
Don't use Expanded inside any scrolling container unless you wrap it in a fixed bound on its main axis.
Like in your case main axis is vertical and you are using expanded in it, since expanded needs a bound to limit its expansion, you should've remove that expanded thing or just wrap the container in a SizedBox for a specific height.
Than you can wrap the sized box in any scroll container which suits you.
Hope it helps!
In your code, change Column to ListView, and remove the expanded widget. you can use fixed height or MediaQuery.of(context).size.height * (any ratio) to the containers, or just don't specify any container height so it'll take its children's height.
here's the code will look like:
body: ListView(
shrinkWrap: true,
children: <Widget>[
Container(
// height: MediaQuery.of(context).size.height * (any ratio) / fixed height
child: Text(
mydata[0][i.toString()],
style: TextStyle(fontSize: 16.0, fontFamily: "Quando"),
),
),
Container(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
choiceButton('a'),
choiceButton('b'),
choiceButton('c'),
choiceButton('d'),
],
),
),
Container(
alignment: Alignment.topCenter,
child: Text(showtimer,
style: TextStyle(
fontSize: 35.0,
fontFamily: "Times New Roman",
fontWeight: FontWeight.w700)),
)
],
),
I am trying to create a list view that contains 10 data, in each item there four widgets that wraps inside a row.
First i inserted a circle image widget, in next I added expanded widget to divide the text widgets equally.
Almost, I have achieved but i found difficulty in ellipsis the text.
Code
class EmailPage extends StatefulWidget {
#override
_EmailPageState createState() => _EmailPageState();
}
class _EmailPageState extends State<EmailPage> {
GlobalKey _keyRed = GlobalKey();
var name = "Adellena Jacksonnnnnnnnnnnnnnnnnnnnnnnnnnnn";
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
elevation: 0.0,
backgroundColor: greenColor,
title: const Text('Inbox'),
actions: <Widget>[
new IconButton(
icon: new Icon(Icons.edit),
onPressed: () => Navigator.of(context).pop(null),
),
],
),
body: SizedBox(
width: MediaQuery.of(context).size.width,
child: ListView.builder(
shrinkWrap: true,
itemCount: 10,
itemBuilder: (BuildContext context, int index) {
return Padding(
padding: const EdgeInsets.all(10.0),
child: new Row(
children: <Widget>[
SizedBox(
width: 30,
height: 30,
child: CircleAvatar(
backgroundColor: Colors.brown.shade800),
),
Expanded(
child: new Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Expanded(
flex: 4,
child: Container(
child: new Text(
name,
overflow: TextOverflow.ellipsis,
softWrap: false,
style: TextStyle(fontSize: 14),
),
),
),
new Expanded(
flex: 3,
child: new Text(
"&14215",
textAlign: TextAlign.center,
style: TextStyle(fontSize: 12),
),
),
new Expanded(
flex: 3,
child: new Text(
"1000 min ago",
textAlign: TextAlign.end,
overflow: TextOverflow.ellipsis,
style: TextStyle(fontSize: 14),
),
),
],
),
),
],
),
);
}),
));
}
}
Screenshot 1
When we remove overflow: TextOverflow.ellipsis in the text widget look like this [Screenshot 2]
Screenshot 2
In above image i didn't get the full text "AdellenaJacksonnnnnnnnn
", but expanded restrict the widget
how many flex can be shown in it. Problem is ellipsis not working as
expected
Note : When i remove the space in the string var name = "AdellenaJacksonnnnnnnnn"; like this ellipsis working fine
The simplest way:
var name = 'Adellena Jacksonnnnnnnnn';
name = name.replaceAll('', '\u200B');
For simpler to use, you can write an extension:
extension StringExtension on String {
String useCorrectEllipsis() {
return replaceAll('', '\u200B');
}
}
usage:
final name = 'Adellena Jacksonnnnnnnnn'.useCorrectEllipsis();
You could make use of this stupid hack, by splitting the name into, you could modify and actually make use of it if you set any max length for first name.
I have clipped the first name so it won't look like it's overflowing get along with the ui, assume there is no maxlength
Flexible(
child: Text(
tempname[0],
overflow: TextOverflow.clip,
maxLines: 1,
),
),
The last name is set ellipsis to give a hit the name is overflowing
Flexible(
child: Text(
tempname[0],
overflow: TextOverflow.ellipsis,
),
),
ListView.builder(
shrinkWrap: true,
itemCount: 10,
itemBuilder: (BuildContext context, int index) {
var tempname = name.split(' ');
return Padding(
padding: const EdgeInsets.all(10.0),
child: new Row(
mainAxisSize: MainAxisSize.max,
children: <Widget>[
SizedBox(
width: 30,
height: 30,
child: CircleAvatar(
backgroundColor: Colors.brown.shade800),
),
Expanded(
child: new Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Expanded(
flex: 4,
// width: 100,
child: Row(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Flexible(
child: Text(
tempname[0],
overflow: TextOverflow.clip,
maxLines: 1,
),
),
Text(' '),
Flexible(
child: Text(
tempname[1],
overflow: TextOverflow.ellipsis,
),
)
],
),
),
new Expanded(
flex: 3,
child: new Text(
"&14215",
textAlign: TextAlign.center,
style: TextStyle(fontSize: 12),
),
),
new Expanded(
flex: 3,
child: new Text(
"1000 min ago",
textAlign: TextAlign.end,
overflow: TextOverflow.ellipsis,
style: TextStyle(fontSize: 14),
),
),
],
),
),
],
),
);
}),
name = 'Adellenaddddddddddddd Jacksoonnnnnnnnnn';
name = 'Nadeem Jacksoonnnnnnnnnn';
overflow: TextOverflow.fade did the trick for me.
Try with flexible instead of Expanded because. Official Documentation
Using a Flexible widget gives a child of a Row, Column, or Flex the flexibility to expand to fill the available space in the main axis (e.g., horizontally for a Row or vertically for a Column), but, unlike Expanded, Flexible does not require the child to fill the available space.
try to type the surname seperated like that jackson nn nn nnn nnn that will work better