Unable to wrap Text inside Container in Flutter - flutter

I have the following tree: Scaffold > Column > Row > Container > Text.
I want the Text to wrap, and The Great Google in most cases told me that Expanded is what i need, but none of the below cases worked for me:
Row wrapped inside Expanded
Container wrapped inside Expanded
Text wrapped inside Expanded
All of the above have the same result.
Here's my code for the page's body:
import 'package:flutter/material.dart';
class HomePage extends StatelessWidget {
const HomePage({super.key});
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: const Color(0xFF282B32),
body: Column(
children: <Widget>[
createRow(
context,
"https://i.stack.imgur.com/6Utrc.jpg?s=256&g=1",
"GuildProtect is a powerful, baterries-included moderation bot for your *safe* server!"
),
createDivider(),
createRow(
context,
"https://cdn.discordapp.com/avatars/967406876029501462/bd3c60dcf55c83fba41b15fba89f798a.webp?size=256",
"This is a very beatiful (because it's pink) avatar of this shitty website creator, enjoy!"
)
]
)
);
}
Row createRow(BuildContext context, String imageUrl, String text) {
const containerHeight = 256.0;
return Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Container(
alignment: Alignment.centerLeft,
height: containerHeight,
padding: const EdgeInsets.only(left: 50, top: 25, bottom: 25),
child: Image.network(imageUrl),
),
Container(
alignment: Alignment.centerRight,
height: containerHeight,
padding: const EdgeInsets.only(right: 50, top: 25),
child: Text(
text,
style: TextStyle(
color: const Color(0xFFFFFCF9),
fontWeight: FontWeight.bold,
fontSize: DefaultTextStyle.of(context).style.apply(fontSizeFactor: 1.3).fontSize,
),
),
),
]
);
}
Divider createDivider() {
return const Divider(
color: Color(0xFF131518),
indent: 30,
endIndent: 30,
thickness: 1,
height: 20,
);
}
}
I also saw some answers on SO recommending to cut the text or show ellipsis, but i dont need this behaviour, i need the text to actually wrap. This video's second solution shows exactly what i want to achieve (and no, the solution from there didn't help).
Any help is appreciated!

In createRow(), wrap the second Container() with Flexible().
Flexible(
child: Container(
alignment: Alignment.centerRight,
height: containerHeight,
padding: const EdgeInsets.only(right: 50, top: 25),
child: Text(
text,
style: TextStyle(
color: const Color(0xFFFFFCF9),
fontWeight: FontWeight.bold,
fontSize: DefaultTextStyle.of(context)
.style
.apply(fontSizeFactor: 1.3)
.fontSize,
),
),
),
)
Lemme know if it worked for your use case.

Why are you seeing this?.
Well, this is because the width of the widgets which you are trying to put, is greater then the screen size.
Possible solutions:
Try to add width property to the second Container in the Row
try to use .fit property, which will fit the image in it's father widget size.
I don't think that wrapping the container in Expanded wouldn't fix the situation as I see the text is too long (the screen has overflowed by 260 pixels).
Try to use TextOverflow as mentioned in link.
Please, let me know if any of my solutions works.

Anywhere you want to use a text and its length is not specified, you may encounter a folding error.
My suggestion is to use Expanded.
This is the output of your code snippet in my simulator
your code Output in mobile
It is enough to wrap the second Container with an Expanded widget (createRow) :
Row createRow(BuildContext context, String imageUrl, String text) {
const containerHeight = 256.0;
return Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Container(
alignment: Alignment.centerLeft,
height: containerHeight,
padding: const EdgeInsets.only(left: 50, top: 25, bottom: 25),
child: Image.network(imageUrl),
),
--> Expanded(
child: Container(
alignment: Alignment.centerRight,
height: containerHeight,
padding: const EdgeInsets.only(right: 50, top: 25),
child: Text(
text,
style: TextStyle(
color: const Color(0xFFFFFCF9),
fontWeight: FontWeight.bold,
fontSize: DefaultTextStyle.of(context).style.apply(fontSizeFactor: 1.3).fontSize,
),
),
),
),
]
);
}
and output:
--> after Wrap Container with Expanded Widget
It is noteworthy that this part of your work is not responsive.
Probably, the texts are too big in my emulator because of the difference made by the DefaultTextStyle.of(context) class.
Anyway, I hope it solved your problem.
full code:
I used MediaQuery for setting fontSize Because no details are provided from the content of the defaultTextStyle class.
import 'package:flutter/material.dart';
class TstPage extends StatelessWidget {
const TstPage({super.key});
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: const Color(0xFF282B32),
body: Column(
children: <Widget>[
createRow(
context,
"https://i.stack.imgur.com/6Utrc.jpg?s=256&g=1",
"GuildProtect is a powerful, baterries-included moderation bot for
your *safe* server!"
),
createDivider(),
createRow(
context,
"https://cdn.discordapp.com/avatars/967406876029501462/bd3c60dcf55c83fba41b15fba89f798a.webp?size=256",
"This is a very beatiful (because it's pink) avatar of this shitty
website creator, enjoy!"
)
]
)
);
}
Row createRow(BuildContext context, String imageUrl, String text) {
const containerHeight = 256.0;
return Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Container(
alignment: Alignment.centerLeft,
height: containerHeight,
padding: const EdgeInsets.only(left: 50, top: 25, bottom: 25),
child: Image.network(imageUrl),
),
Expanded(
child: Container(
alignment: Alignment.centerRight,
height: containerHeight,
padding: const EdgeInsets.only(right: 50, top: 25),
child: Text(
text,
style: TextStyle(
color: const Color(0xFFFFFCF9),
fontWeight: FontWeight.bold,
fontSize: MediaQuery.of(context).size.width*0.04,
),
),
),
),
]
);
}
Divider createDivider() {
return const Divider(
color: Color(0xFF131518),
indent: 30,
endIndent: 30,
thickness: 1,
height: 20,
);
}
}

Related

Flutter: Space above Divider line is not the same as below

Here's my code:
import 'package:flutter/material.dart';
class HomePage extends StatelessWidget {
const HomePage({super.key});
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: const Color(0xFF282B32),
body: Column(
children: <Widget>[
createRow(
context,
"https://i.stack.imgur.com/6Utrc.jpg?s=256&g=1",
"GuildProtect is a powerful, baterries-included moderation bot for your *safe* server!"
),
createDivider(),
createRow(
context,
"https://cdn.discordapp.com/avatars/967406876029501462/bd3c60dcf55c83fba41b15fba89f798a.webp?size=256",
"This is a very beatiful (because it's pink) avatar of this shitty website creator, enjoy!"
)
]
)
);
}
Row createRow(BuildContext context, String imageUrl, String text) {
const containerHeight = 256.0;
return Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Container(
alignment: Alignment.centerLeft,
height: containerHeight,
padding: const EdgeInsets.only(left: 50, top: 25),
child: Image.network(imageUrl),
),
Container(
alignment: Alignment.centerRight,
height: containerHeight,
padding: const EdgeInsets.only(right: 50, top: 25),
child: Text(
text,
style: TextStyle(
color: const Color(0xFFFFFCF9),
fontWeight: FontWeight.bold,
fontSize: DefaultTextStyle.of(context).style.apply(fontSizeFactor: 1.3).fontSize,
),
),
),
]
);
}
Divider createDivider() {
return const Divider(
color: Color(0xFF131518),
indent: 30,
endIndent: 30,
thickness: 1,
height: 20,
);
}
}
Here's the result:
Result
It's becomes clear when looking at divider line near the images that space above divider and up to first image is not the same as space below divider and down to the second image.
I want to divider's height divide by 2 and take the same amount of space below and above divider. Any clue how to do it?
The padding is only applied on top
return Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Container(
alignment: Alignment.centerLeft,
height: containerHeight,
padding: const EdgeInsets.only(left: 50, top: 25),
It would be better to include bottom as well.
padding: const EdgeInsets.only(left: 50, top: 25,bottom:25 ),
I will prefer wrapping the top row with padding widget in this case or using SizedBox/Padding around createDivider

Child Container's Height is depending on parent Container's Widget

I Creating a Container giving it a height and width responsively, but the issue is that in the child of Container I use a ListView to show some Cards which are basically container and I give them a constant height but the height of the card are totally depending on Container's height, even if I give the of cards to 0, nothing will happen, and when I increase the container height, the card height increases, same happens while decreasing. this never happens to me before in flutter, may be this is a new version, I need help, please give answers with an explanation. You can see the Code of the container and Card.
Container Code
Padding(
padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 0),
child: Container(
child: ListView(
scrollDirection: Axis.horizontal,
children: sample
.map((obj) => card.PredictionCard(
temprature: obj.temprature, status: obj.status))
.toList(),
),
height: _device.height * 0.22,
decoration: cardDecoration,
),
),
Card Code
class PredictionCard extends StatelessWidget {
final temprature;
final status;
const PredictionCard({this.temprature, this.status});
#override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 8.0),
child: Container(
margin: EdgeInsets.symmetric(
vertical: 10,
),
height: 120,
decoration: predictionCardDecoration,
width: 100,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
'$temprature',
style: TextStyle(
color: Colors.white,
fontSize: 40,
),
),
Text(
'$status',
style: TextStyle(
color: Colors.white, fontSize: 15, letterSpacing: 1),
),
SizedBox(height: 5),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
crossAxisAlignment: CrossAxisAlignment.end,
children: [
Column(
children: [
Image(
image: AssetImage('assets/rainIcon.png'),
),
Text(
'23%',
style: TextStyle(
color: Colors.white, fontSize: 15, letterSpacing: 1),
),
],
),
Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Image.asset('assets/rainDropIcon.png'),
Text(
'0%',
style: TextStyle(
color: Colors.white, fontSize: 15, letterSpacing: 1),
),
],
),
],
)
],
),
),
);
}
}
Code of Class from where Responsive height is integrated
// widget binging method
class DeviceConfig {
final height = WidgetsBinding.instance.window.physicalSize.height /
WidgetsBinding.instance.window.devicePixelRatio;
final width = WidgetsBinding.instance.window.physicalSize.width /
WidgetsBinding.instance.window.devicePixelRatio;
}
// using media query {uses context to set value of device configuration}
class DeviceConfigQuery {
var height;
var width;
DeviceConfigInit(BuildContext context) {
height = MediaQuery.of(context).size.height;
width = MediaQuery.of(context).size.width;
}
}
Ok I will allow myself to copy the answer from another post as its worth to remember that and I woudnt put it better.
Constraints in Flutter works a bit different than usual. Widgets
themselves do not have constraints.
When you specify a width/height on a Container, you're not
constraining Container. You're constraining the child of Container.
Container will then size itself based on the size of its child.
As such, parent widgets always have the last word on how their
descendants should be sized.
If you want to go around this, you have to use Align widget:
Container(
width: 200.0,
height: 200.0,
child: Align(
alignment: Alignment.topLeft,
child: Container(
width: 50.0,
height: 50.0,
decoration: BoxDecoration(shape: BoxShape.circle, color: Colors.red),
),
),
);
This may seem weird and limiting. But this single weirdness is the
reason why Flutter's layout is so powerful and composable.
answered by:
RĂ©mi Rousselet in this post https://stackoverflow.com/a/54717843/2945977
In your example instead of using Padding, use Align with alignment: Alignment.center

SingleChildScrollView makes the UI white

I am trying to make my UI scrollable but when i add the SingleChildScrollView i get this white screen not showing anything at all.I should erase the Column from the begining?Use a container?I already search on internet but i don't know what to add.
Here is my code, please tell me what i can erase or add to make it work ..
class _UserProfilesState extends State<UserProfiles> {
#override
#override
Widget build(BuildContext context) {
return Scaffold(
body: SingleChildScrollView(
child: Column(
children: <Widget>[
Expanded(
child: Stack(
children: <Widget>[
Padding(
padding:
EdgeInsets.symmetric(horizontal: 10.0, vertical: 40.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
IconButton(
icon: Icon(Icons.arrow_back),
iconSize: 30.0,
color: Colors.black,
onPressed: () => Navigator.pop(context),
),
])),
Positioned(
left: 24,
top: MediaQuery.of(context).size.height / 6.5 - 28,
child: Container(
height: 84,
width: 84,
//profilepic
child: CircleAvatar(
radius: 10,
backgroundImage: NetworkImage(widget.avatarUrl != null
? widget.avatarUrl
: "https://icon-library.com/images/add-image-icon/add-image-icon-14.jpg"),
),
),
),
Positioned(
right: 24,
top: MediaQuery.of(context).size.height / 6.5 + 16,
child: Row(
children: <Widget>[
Container(
height: 32,
width: 100,
child: RaisedButton(
onPressed: () {
Navigator.of(context).push(MaterialPageRoute(
builder: (context) => ChatScreen(
serviceProviderId:
widget.serviceProviderId,
userName: widget.userName,
avatarUrl: widget.avatarUrl,
)));
},
color: Colors.black,
textColor: Colors.white,
child: Text(
"Message",
style: TextStyle(fontWeight: FontWeight.bold),
)),
),
SizedBox(
width: 16,
),
Container(
height: 32,
width: 32,
decoration: BoxDecoration(
image: DecorationImage(
image: NetworkImage(
"https://lh3.googleusercontent.com/Kf8WTct65hFJxBUDm5E-EpYsiDoLQiGGbnuyP6HBNax43YShXti9THPon1YKB6zPYpA"),
fit: BoxFit.cover),
shape: BoxShape.circle,
color: Colors.blue),
),
],
),
),
Positioned(
left: 24,
top: MediaQuery.of(context).size.height / 4.3,
bottom: 0,
right: 0,
child: Container(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(widget.userName,
style: TextStyle(
color: Colors.black,
fontWeight: FontWeight.bold,
fontSize: 22,
)),
SizedBox(
height: 4,
),
Padding(
padding: const EdgeInsets.all(1.0),
child: Text(
widget.address == "default"
? "No Address yet"
: "${widget.address}",
style: TextStyle(
color: Colors.black,
fontSize: 12,
),
)),
Padding(
padding: const EdgeInsets.all(1.0),
child: Text(
"${widget.categoryName}",
style: TextStyle(
color: Colors.black,
fontSize: 12,
),
)),
],
),
))
],
))
],
),
),
);
}
}
Using Spacer() might also cause this issue
The reason why your UI became white is that SingleChildScrollView allows it child to take as much space as possible. In your Column, one of your children is Expanded, Expanded tries to take as much space as possible. You are making your UI take an infinite amount of space because of that. That's the reason why you are seeing a white screen. The solution here would be to remove Expanded.
according to me and the knowledge I have this happened because the singlechildscrollview here tries to take as much height as it can take so It is creating an issue to solve this wrap the singlechildscrollview in a container and give height&width to the container it solved in my case
Thanks...
I faced similar issues, but after much research I got it working, by ensuring that the body of the scaffold be a Container that defines it's height and width, or Column. After which you can wrapped your any of these with a SingleChildScrollView.
However, in an attempt to insert an Expanded widget as child element, the expanded widget will look for bounded heights of it's parents/root element. And if it doesn't found any, it will thrown an error. A good example is if the root element is a column or a container with an unbounded height. Which is your case, looking at your code

Auto expanding Container in flutter -- for all devices

I need a Container with some text in to auto expand. I have an API call, which can be anything from 5 words to 500 words. I don't want to just have 1 fixed size that's huge, but contains 10 words.
I have tried Expanded() and SizedBox.Expand(), but I might be using them wrong
Card(
elevation: defaultTargetPlatform ==
TargetPlatform.android ? 5.0 : 0.0,
child: Column(
children: <Widget>[
Container(
margin: const EdgeInsets.all(0.0),
padding: const EdgeInsets.all(2.0),
decoration: BoxDecoration(color: Colors.black),
width: _screenSize.width,
height: 250,
child: Column(
children: <Widget>[
Container(
color: Colors.black,
width: _screenSize.width,
height: 35,
child: Padding(
padding: const EdgeInsets.only(
left: 15, top: 11),
child: Text("Title".toUpperCase(),
style: TextStyle(
color: Colors.white
),
),
),
),
Container(
color: Colors.white,
width: _screenSize.width,
height: 210,
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Padding(
padding: const EdgeInsets.only(top: 8, bottom: 5),
child: Text("Title of expanding text", style: TextStyle(
fontSize: 25,
),
),
),
Text("Expanding text", style: TextStyle(
fontSize: 35,
fontWeight: FontWeight.w800
),),
],
),
),
],
),
),
],
),
),
I just need the Container to expand, but stay small/get bigger
Have you tried not specifying height at all? The Container should wrap according to the child in this case.
Otherwise, the widget has a child but no height, no width, no
constraints, and no alignment, and the Container passes the
constraints from the parent to the child and sizes itself to match the
child.
Above is an extract from the official flutter documentation for Container.
Here is the official flutter documentation link.
You can use FittedBox, this will resize your text according to available area.
You can use it like this :
FittedBox(child: Text('...............Your text...............'));
I would suggest you to use Constraints...this will set Container height according to the Text child's requirement. Please see the example...
Container(
constraints: BoxConstraints(
maxHeight: double.infinity,
),
child: Column(
children: [
Text(
'Hello flutter...i like flutter...i like google...',
softWrap: true,
style: TextStyle(
color: Colors.white, fontSize: 20 , ),
),],),)
we just neeed to add mainAxisSize: MainAxisSize.min, properties inside child Column or Row where the child is set to Container
for example
AnythingYourWidget(
child: Container(
child: Column( // For Example Column
mainAxisSize: MainAxisSize.min, // these properties following the children content height available.
children: [
// YourWidget
]
)
)
),
I too had a container with a text widget inside that would not scale as the text increased in character count. Make the widget tree Container -> IntrinsicWidth -> Text/TextField and it seems to play nicely for me.
IntrinsicWidth will scale the size of the container to its child.

How to set a fix space between Row items

I have a Row containing a small image followed by a Text. I'm trying to set a fix space between those 2 widgets (for the moment they are stuck one after the other). That should be something simple but I don't know a nice way to do it...
Here is my code:
Widget displayRow(String imageName, String text, TextStyle textStyle) {
Widget widget = Container(
margin: const EdgeInsets.symmetric(vertical: 8.0),
color: Colors.green,
child: Row (
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Image.asset(
"images/${imageName}",
width: 32.0,
height: 32.0,
alignment: Alignment.center,
fit: BoxFit.scaleDown
),
Text(text, style: textStyle),
],
),
height: 120.0,
);
return widget;
}
I have put this code in a function because I intend to use it several times to display different rows all on the same pattern (an image + a text).
Thanks for the help
You can use a Container with a relatively small width:
Widget displayRow(String imageName, String text, TextStyle textStyle) {
Widget widget = Container(
margin: const EdgeInsets.symmetric(vertical: 8.0),
color: Colors.green,
child: Row (
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Image.asset(
"images/${imageName}",
width: 32.0,
height: 32.0,
alignment: Alignment.center,
fit: BoxFit.scaleDown
),
Container(width: 10.0), // You can adjust it to suit your design
Text(text, style: textStyle),
],
),
height: 120.0,
);
return widget;
}
You can also opt for wrapping the Image widget inside a Container and giving it a certain padding :
Container(
padding: EdgeInsets.all(15.0),
child: Image.asset(
"images/${imageName}",
width: 32.0,
height: 32.0,
alignment: Alignment.center,
fit: BoxFit.scaleDown
),
),