How to make SVG image to use available space? (and to avoid size-hardcoding) - flutter

I have an SVG image as a child (at the begin) of a Row. I have wrapped it in a FractionallySizedBox() to make sure that image takes a certain amount of space in a Row. Now, I want Image to use that space, without setting fix width or height (since it can make problems on different devices).
I have used attribute fit: BoxFit.scaleDown, but it is not working.
Any suggestions? :)
here my code:
Row(
children: [
Flexible(
child: FractionallySizedBox(
widthFactor: 0.65,
child: Padding(
padding: const EdgeInsets.all(10),
child: SvgPicture.asset('assets/image.svg',
fit: BoxFit.scaleDown
//width: 60,
),
),
),
),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(item.name,
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.left),
Text(
item.type,
textAlign: TextAlign.left,
),
]),
),

Related

How can I make a text take a fixed width based on the length of a string in flutter?

I have a widget tree as follows:
Widget example() {
return Column(
children: [
Row(
children: [
Expanded(
child: Container(
height: 100,
decoration: BoxDecoration(color: Colors.red),
),
),
Text('25.00%')
],
),
Row(
children: [
Expanded(
child: Container(
height: 100,
decoration: BoxDecoration(color: Colors.red),
),
),
Text('125.00%')
],
),
Row(
children: [
Expanded(
child: Container(
height: 100,
decoration: BoxDecoration(color: Colors.red),
),
),
Text('1250.00%')
],
),
],
);
}
How can I make all texts take the same horizontal space without using pixels in width so that all containers are aligned vertically?
I would like to set a fixed length for my percentages and the ones that are shorter are padded with spaces and the ones that are longer get cropped with the text elipsis.
Is there a clean build in method to do that?
Since your requirement is to set a fixed width for the percentages and ellipsize the text if it overflows, I'll suggest that you wrap your Text widget too inside an Expanded widget and use flex property for both the expanded components of the row. I'm suggesting a ratio of 5:1 between both components of the row, represented by flex1 and flex2 respectively. However, you may set the flex as per your requirement.
Secondly, I've used overflow: TextOverflow.ellipsis in all of the Text widgets that will take care of the ellipsis part of your requirement.
I've also aligned the text to right but that's totally up to u.
Following is the revised code:
Widget example2() {
int flex1 = 5;
int flex2 = 1;
return Column(
children: [
Row(
children: [
Expanded(
flex: flex1,
child: Container(
height: 100,
decoration: BoxDecoration(color: Colors.red),
),
),
Expanded(
flex: flex2,
child: const Text('25.00%',
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.right,
),
)
],
),
Row(
children: [
Expanded(
flex: flex1,
child: Container(
height: 100,
decoration: BoxDecoration(color: Colors.red),
),
),
Expanded(
flex: flex2,
child: const Text('125.00%',
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.right,
),
)
],
),
Row(
children: [
Expanded(
flex: flex1,
child: Container(
height: 100,
decoration: BoxDecoration(color: Colors.red),
),
),
Expanded(
flex: flex2,
child: const Text(
'1250.00%',
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.right,
),
)
],
),
],
);
}
Hope it helps!
the solution for all those issues is in the auto_size_text package, you can set a maxLines to set the maximum lines an AutoSizeText so if you have multiple AutoSizeText widgets, all will take the same horizontal space because however, your text is long, the package will resize it to fit in the specific lines ranges, otherwise, you can give it ellipsis style.
AutoSizeText(
yourText,
maxLines: 1,
minFontSize: 10,
wrapWords: false,
overflow: TextOverflow.ellipsis,
);

Text Overflowing in a Row, Flutter

I'm having issues with the layout because of the long text, I've tried using Expanded / Flexible with the text that is causing the issue to fill the space it needs but it's overflowing. I know the question is asked hundred times, but I don't understand where is the mistake. I tried applying to both Expanded / Flexible to all of the Row/Columns individually and too all at the same time (mostly I was trying out layouts to try to fix it), and I still have the issue... I even tried to use the FittedBox with fit: BoxFit.(all of them).
Container(
alignment: Alignment.centerLeft,
child: Column(
children: [
Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Padding(
padding: const EdgeInsets.only(right: 8.0),
child: Icon(Icons.directions_car),
),
Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text("Text 1"),
SizedBox(
height: 4,
),
Text('TEXT 2'),
],
),
SizedBox(
width: 27,
),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('1 World Way, Los Angeles, CA 90045, USA',
textAlign: TextAlign.left,
),
SizedBox(
height: 4,
),
Text('FLIGHT 3231'),
],
),
],
),
],
),
],
),
);
By my understanding, and do correct me if I'm wrong, applying Expanded / Flexible, Flexible takes only the needed space, and Expanded takes all available space, respecting the flex factor. So most of the time I use the Flexible widget, but this time it is not working.
Thanks in advance for the help!
Try using Expanded widget with flex value set as per the expectation of UI filling.
Sample Code:
Center(
child: Container(
height: 80,
color: Colors.yellow,
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Padding(
padding: const EdgeInsets.all(8.0),
child: Icon(Icons.bus_alert),
),
Expanded(
flex: 1,
child: Container(
width: 1,
color: Colors.green,
child: Column(
children: [Text("Text 1"), Text("Text 1")],
),
)),
Expanded(
flex: 3,
child: Container(
color: Colors.blue,
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
Text("1 World Way, Los Angeles, CA 90045, USA"),
Text("FLIGHT 3231"),
],
),
))
],
),
))
Note: There is a limitation for the text content using. We need to make sure to set the height according to the expected text length.
You can use Flexible or Expanded Widget You should try to below code :
Card(
shape: RoundedRectangleBorder(
side: BorderSide(
color: Colors.blue,
),
borderRadius: BorderRadius.circular(15.0),
),
margin: EdgeInsets.all(16.0),
child: Container(
padding: EdgeInsets.all(8.0),
alignment: Alignment.centerLeft,
child: Column(
children: [
Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Icon(Icons.directions_car),
SizedBox(
width: 10,
),
Flexible(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text("Text 1"),
SizedBox(
height: 4,
),
Text('TEXT 2'),
],
),
),
SizedBox(
width: 27,
),
Flexible(
child: Container(
child: Column(
children: [
Text(
'1 World Way, Los Angeles, CA 90045, USA',
textAlign: TextAlign.left,
),
SizedBox(
height: 4,
),
Text(
'FLIGHT 3231',
textAlign: TextAlign.left,
),
],
),
),
),
],
),
],
),
),
),
Your screen like this :
wrap it by a container with fixed width and then use auto_sized_text. Or you can wrap your Text widget by FittedBox by fixed width. it would do the same approach. Feel free to add maxLine, minFontSize and maxFontSize' in auto_sized_text. Using ExpandedorFlexible` only affects the size of the container when your text length is lower than the given width, and It does not help you in this situation.
If the text is really long, then using Expanded will wrap the text according to the parent widget, thus leading to change in the font size. You might consider using ellipsis.
return Container(
width:300 //give a width of your choice
child: Text('Any long text',
overflow:TextOverflow.ellipsis,
),
);

Flutter - Expanded within Flexible

My Row is composed of two Flexible and one of them is a Column I would like this column to take all the available vertical space like in my original design.
I tried to wrap the Column with an Expanded but it seems that I can't. I tried the property Flexible.tight of the flexible but it didn't work.
Row(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Flexible(
flex: 2,
child: SizedBox(
height: 130.0,
width: 130.0,
child: ClipRRect(
borderRadius: BorderRadius.circular(35.0),
child: CachedNetworkImage(
imageUrl: fakeOffers[index].imageUrl,
fit: BoxFit.cover,
placeholder: (context, url) => MC_Shimmer(),
),
),
),
),
Flexible(
flex: 3,
fit: FlexFit.tight,
child: Container(
child: Padding(
padding: const EdgeInsets.only(left: 15.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
mainAxisSize: MainAxisSize.max,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
fakeOffers[index].title,
style: MC_favoriteOfferTitle,
maxLines: 2,
overflow: TextOverflow.ellipsis,
),
Text(
fakeOffers[index].price.toStringAsFixed(0) + ' €',
style: MC_priceGradientDetail,
),
Text(
fakeOffers[index],
style: MC_favoriteOfferMeta,
),
],
),
),
),
)
],
);
You need to drop the first Flexible (it's fixed size anyway) and convert the second Flexible to an Expanded. This will let this Expanded take up all remaining space. Then, your column needs to take up all available space using CrossAxisAlignment.stretch.
So to solve the problem I just set the height of the column to 130.0 as I have a fixed size image.

overflowing flutter columns and rows

I have this list view in flutter which I am trying to make into a chat list. Similar to what you see in WhatsApp and telegram. However I am struggling to get the idea of how rows and columns work because I keep getting overflows.
Here is the code:
ListView(
physics: BouncingScrollPhysics(),
children: [
Dismissible(
key: Key(""),
background: Container(color: Colors.grey[200]),
direction: DismissDirection.endToStart,
child: InkWell(
onTap: () {},
child: Column(
mainAxisSize: MainAxisSize.max,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Flex(
direction: Axis.vertical,
children: [
Text("Hello"),
],
),
Flex(
direction: Axis.vertical,
children: [
Text(
"al;skdl;aksd a;skd ;aks;dk a;skd ;laks;d a;lsk d;lkas; dka;lsk d;laks; ldka;slk d;a",
overflow: TextOverflow.ellipsis,
maxLines: 2,
),
],
),
],
),
),
),
],
Now we often experience the text overflow problem so if we think it that we we have provided column a particular width and restricted it but if we wrap the things up with flexible widget it now tells column/Row that you can change your size and be flexible
order would be
flexible > Container > Column/Row
The reason we are applying this to container is Column/Row will ask immediate parent for width and height
now this problem can also be solved by text overflow property that is we can clip text but what if we dont want too
So all you have to do is Wrap the column/Row in Container and then into Flexible as now it will tell container that yes you can adjust your height
Your concept can be cleared by how actually widgets parent child relationship works i.e in brief
basically If am a child I will ask my parent okay what is my size so since my parent if it has a size it will bound me but if it doesnt has a size it will ask its parent okay tell me what space should I take and it goes on. Expanded and Flexible says that okay you can adjust yourself instead of being Fixed.
Flexible(
child: Container(
margin: EdgeInsets.only(left: 10.0,right: 10.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('${dataBookTitleSearch1[index]} ', style: kGoodSearchResultTextStyle, textAlign: TextAlign.left,),
SizedBox(
height: 10.0,
),
Text('${dataBookAuthorSearch1[index]}', style: kGoodSearchResultTextStyle,textAlign: TextAlign.left),
SizedBox(
height: 10.0,
),
Text('${dataBookExtensionSearch1[index]} ', style: kGoodSearchResultTextStyle,textAlign: TextAlign.left),
SizedBox(
height: 20.0,
),
Container(
width: 80.0,
height: 40.0,
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(20.0)),
color: Colors.white
),
child: Padding(
padding: const EdgeInsets.only(left:20.0,top: 12.0),
child: Text('Read'),
),
),
],
),
),
)

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.