Why can't make containers have the same width inside the Row - flutter

This question has been asked many times but none of the methods worked for me.
I've been trying to make these containers have the same width and height. I tried using Expanded but apperantly, it expands the children to fit the layout, which I don't want. In fact, I want to align them similar to MainAxisAlignment's Spacearound property does. I also used Sizedboxes, but not surprisingly, it made my app deprived of responsiveness.
First of all, I put my containers inside a Row widget
Flexible(child: Row(mainAxisAlignment : MainAxisAlignment.spaceAround, children:
categories(textList: [['EK-FİİL YOK', 'a'], ['İSMİ YÜKLEM YAPMA', 'b'], ['BİRLEŞİK ZAMAN KURMA', 'c']],
callback: callback, category: horizontalCategory),))
Here, I create multiple containers by for loop; horizontalCategory(element[0]) returns a Container
List<Widget> categories({required List<List<String>> textList, required Function callback}) {
List<Widget> containers = [];
for (var element in textList) {
containers.add(DragTarget<DraggableText>(
builder: (
BuildContext context,
List<dynamic> accepted,
List<dynamic> rejected,
) => horizontalCategory(element[0])
, onAccept: (DraggableText data) {
callback(data, element[1]);
}));
}
return containers;
This code creates one container:
Widget horizontalCategory(String text) {
return Container(
decoration: BoxDecoration(
borderRadius: const BorderRadius.all(Radius.circular(8)),
border: Border.all(width: 2,color: Colors.blueGrey),
color: Colors.lightBlue.withOpacity(0.04),
),
padding: const EdgeInsets.symmetric(horizontal: 8),
child: Center(
child: Text(
text, style: const TextStyle(fontWeight: FontWeight.bold, ), textAlign: TextAlign.center,
),
),
);
}
Expected Output: same width and height
Actual Output

Remove your parent Flexible from Row and then wrap each child around with Flexible:
Row(
children: [
Flexible(child:horizontalCategory('x')),
Flexible(child:horizontalCategory('y')),
Flexible(child:horizontalCategory('z')),
]
),

Wrap your Container inside an Expanded (And because they all have flex: 1, they should be the same size)
Expanded(
child: Container(
decoration: BoxDecoration(
borderRadius: const BorderRadius.all(Radius.circular(8)),
border: Border.all(width: 2,color: Colors.blueGrey),
color: Colors.lightBlue.withOpacity(0.04),
),
padding: const EdgeInsets.symmetric(horizontal: 8),
child: Center(
child: Text(
text, style: const TextStyle(fontWeight: FontWeight.bold, ), textAlign: TextAlign.center,
),
),
,)
);

Related

Getting a Container inside an Expanded inside a Row to expand vertically to fit the space available in the Row

I have a row containing four Expanded widgets. Its code looks as follows:
Row(
children: [
Expanded(
child: Container(
width: double.infinity,
color: Colors.blueGrey,
padding: const EdgeInsets.all(10),
child: (Text(
lessonData.language,
style: const TextStyle(
color: Colors.white,
),
)),
),
),
Expanded(
flex: 1,
child: Container(
width: double.infinity,
color: Colors.blueGrey,
padding: const EdgeInsets.all(10),
child: (Text(
lessonData.cEFRLevelName,
style: const TextStyle(
color: Colors.white,
),
)),
),
),
Expanded(
flex: 1,
child: Container(
width: double.infinity,
color: Colors.blueGrey,
padding: const EdgeInsets.all(10),
child: (Text(
lessonData.lessonTopic,
style: const TextStyle(
color: Colors.white,
),
)),
),
),
Expanded(
child: Container(
width: double.infinity,
color: Colors.blueGrey,
padding: const EdgeInsets.all(10),
child: (
Text(
lessonData.lessonHeading,
style: const TextStyle(
color: Colors.white,
),
)),
),
)
],
),
The resulting display is unsatisfactory if any of the texts in the Containers inside the Expanded widgets are forced to wrap. As in this image:
Click here to display an image of my problem when text has wrapped in one Container but not in the other three.
This image shows something like what I'd like the Row to look like.
I simply can't get the Container widgets containing text without any wrap to expand out to the height of the row.
Among other candidate solutions, I've tried setting the height to double.infinity and double.maxFinite, setting Constraints in the Containers to Constraints: BoxConstraints.expand(). All these options either do nothing or generate an error on hot reload.
I'm reluctant to try an IntrinsicHeight widget because I'm warned that it's very hungry.
I'd be very grateful for any solution and/or comment you might have!
TIA
Jaime
If I understood what you want, I may have a suggestion. It's more of a workaround, but you can move the Container with the colored backgroud up a level and remove each other Container, making the new Container the parent of the whole Row: I put the code in a DartPad, and this is how it looks.
Just an excerpt of the code:
Container(color: Colors.red,child: Row(
children: [
Expanded(...),
Expanded(...),
//and so on...
This works only on an aesthetic level: each Text will still get resized, but you won't notice.

Flutter override app locale for a specific widget only

I am developing a multi language application supports Locale('en') (English) and Locale('ar') (Arabic) , I have a Row() with four children :
Row(
children: [
Flexible(
child: Container(
padding: const EdgeInsets.all(20),
margin: const EdgeInsets.all(10),
child: Text(
"1",
style: TextStyle(color: Colors.white),
),
color: Colors.blue,
),
),
Flexible(
child: Container(
padding: const EdgeInsets.all(20),
margin: const EdgeInsets.all(10),
child: Text(
"2",
style: TextStyle(color: Colors.white),
),
color: Colors.blue,
),
),
Flexible(
child: Container(
padding: const EdgeInsets.all(20),
margin: const EdgeInsets.all(10),
child: Text(
"3",
style: TextStyle(color: Colors.white),
),
color: Colors.blue,
),
),
Flexible(
child: Container(
padding: const EdgeInsets.all(20),
margin: const EdgeInsets.all(10),
child: Text(
"4",
style: TextStyle(color: Colors.white),
),
color: Colors.blue,
),
),
],
)
when the locale is Locale('en') children laid out left to right :
and when the locale is Locale('ar') children laid out right to left :
Problem is I need children in this Row() specifically to be laid left to right regardless the current locale , is there any way to achieve this rather than build different widget based on the current locale ?
if(Localizations.localeOf(context).languageCode == 'en'){
// build some widget
}else{
// build different widget
}
Solved by setting the textDirection property on Row() widget to TextDirection.ltr which determines the order to lay children out horizontally and how to interpret start and end in the horizontal direction.

Create two widgets independent of each other

I am not sure if I am missing something here, but in Flutter I want to crate two widgets that can be moved around independently of each other.
My current code is this:
class SurpriseReveal extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Container(
width: double.infinity,
margin: EdgeInsets.all(10),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
"Hi",
style: TextStyle(fontSize: 20, color: Colors.pink[700]),
textAlign: TextAlign.center,
),
InkWell(
onTap: null,
splashColor: Colors.pink[900],
child: Container(
// set your desired height here
height: 150,
// set your desired width here
width: 150,
// decoration property gives it a color and makes it round like a floating action button
decoration: BoxDecoration(
shape: BoxShape.circle,
color: Colors.pink[300],
),
// add your desired padding here
padding: const EdgeInsets.symmetric(vertical: 10.0),
// add the child element
child: Center(
child: Text(
'Hi',
// style of the text
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 22.0,
color: Colors.pink[900],
),
),
),
),
),
],
),
);
}
}
This creates something that looks like this:
What I would like to be able to do is choose the positioning of these widgets on the screen independently of each other. For example, If I wanted to have a gap between the text and the button, or the button off to one side.
Would I need to create two separate functions that return Widget?
To add space between your widgets you can wrap them with a Padding() widget. However, if you want to dispose your widgets independantly wherever on the screen wrap them in a stack widget and use Positionned() widget to set their constrainst.

How to handle overflow of a Row inside a Column inside a Stack in Flutter?

I'm trying to create a simple stack list that for a specific designer reason has the following structure:
Text inside a Padding inside a Row inside a Column inside a Container inside a Positioned inside a Stack inside a Card (although I assume the Card part is irrelevant to the question).
The problem is as follows: once the String inside the Text Widget exceeds a certain amount of characters, it overflows, as shown in the image below:
I've tried wrapping the Text, Row, Column Widgets and so on with a Flexible (or Expanded) Widget, but I get an error message saying "Flexible widgets must be placed inside Flex widgets". I'm pretty sure I lack some knowledge on the Widgets that I'm using, but that knowledge I have not been able to find on the flutter dev website, therefore I have decided to post the question here. This is the code for the Card item in which the Stack is located (I'm not pasting the whole class since other methods and the constructor aren't required to duplicate the error in question and I don't want people to get confused by reading code unrelated to the question):
#override
Widget build(BuildContext context) {
return Card(
child: Stack(
children: <Widget>[
Container(
alignment: Alignment.center,
padding: EdgeInsets.only(bottom: 20.0),
decoration: BoxDecoration(
border: Border.all(width: 3.5, color: Colors.black87),
shape: BoxShape.circle,
image: DecorationImage(
fit: BoxFit.cover,
image: this.image ??
AssetImage(
'images/rolph.jpg',
),
),
),
),
Positioned(
bottom: 0.0,
left: 0.0,
right: 0.0,
child: Container(
decoration: BoxDecoration(
color: Colors.white,
border: Border(
top: BorderSide(width: 3.0, color: Colors.black),
bottom: BorderSide(width: 1.0, color: Colors.black),
right: BorderSide(width: 1.0, color: Colors.black),
left: BorderSide(width: 1.0, color: Colors.black)),
),
child: Column(
children: <Widget>[
Row(
children: <Widget>[
Padding(
padding: EdgeInsets.only(left: 2.0),
child: Text(
this.name,
overflow: TextOverflow.clip,
style: TextStyle(fontSize: 18.0),
),
)
],
),
Row(
children: <Widget>[
Padding(
padding: EdgeInsets.only(bottom: 2.0, left: 3.0),
child: Text(
this.email,
overflow: TextOverflow.ellipsis,
style: TextStyle(fontSize: 16.0),
),
)
],
)
],
),
),
),
_shouldIShowNotificationBubble(),
Positioned(
left: 0.0,
right: 0.0,
top: 0.0,
bottom: 0.0,
child: Container(
color: Colors.transparent,
child: InkWell(
highlightColor: Colors.deepPurple,
onTap: this.onTap ??
() {
debugPrint("Ink is, well, clicked.");
},
),
),
)
],
),
color: Colors.white,
elevation: 4.0,
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(4.0)),
);
}
I hope anyone's got an answer to my problem since I have not been able to find an adequate one on the internet anywhere. Thanks in advance to everyone who participates in answering!
So after a bit of experimenting, the thing that is needed to be done here is to put the Padding widget (the one directly above the problematic widget and directly under the Row (or Column) inside a Flexible (or Expanded) widget. Along with that, what can and should be added to the Text widget is the overflow behavior, such as the following solution:
Row(
children: <Widget>[
Flexible(
child: Padding(
padding: EdgeInsets.only(left: 2.0),
child: Text(
this.name,
maxLines: 2,
overflow: TextOverflow.ellipsis,
style: TextStyle(fontSize: 18.0),
),
),
)
],
Hope this helps others who have stumbled upon the same error. ^_^

Flutter - Text inside an Expanded Widget within a Column overflowing

What I want to achieve is to have a text widget inside a Column of fixed height. When the text is long I want the overflow property which is set to TextOverflow.ellipsis to kick in. The Text widget has its maxLines property set to a high value to allow it to wrap down. But there are other widgets in the column too, both before and after the text widget. The text widget is in an Expanded widget so that it takes up as much room in the column. Full code is pasted below.
The problem with this setup is that the text is overflowing its container parent. I have a border decoration on the container that shows this happening. Why is this happening and how do I fix it.
import 'package:flutter/material.dart';
void main() {
runApp(App());
}
class App extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text("Overflow"),
),
body: Center(
child: Container(
width: 200.0,
height: 250.0,
child: Card(
child: Column(children: <Widget>[
Image.asset(
"assets/bereket.jpg",
width: double.infinity,
fit: BoxFit.cover,
),
Expanded(
child: Container(
padding: EdgeInsets.all(8.0),
child: (Column(
children: [
Text(
"በረከት ስምኦን፡ «ወይዘሮ አና ጎሜዝ፤ እርስዎ አያገባዎትም! አርፈው ይቀመጡ በልልኝ»",
maxLines: 2,
style: Theme.of(context)
.primaryTextTheme
.subhead
.copyWith(
color: Colors.black,
),
overflow: TextOverflow.ellipsis),
Expanded(
child: Container(
decoration: BoxDecoration(
border: Border.all(
color: Colors.green, width: 2.0),
),
child: Text(
"""ባለፉት ሁለት አስርት ዓመታት በኢትዮጵያ ፖለቲካ ከፍተኛ ተጽእኖ ፈጣሪ የነበሩት አቶ በረከት ስምኦን በቅርቡ ከብአዴን ማእከላዊ ኮሚቴ አባልነት መታገዳቸው ይታወሳል።
አቶ በርከት የብአዴን ውሳኔን በተመለከተ እና የወደፊት የፖለቲካ ህይወታቸው ምን ሊሆን እንደሚችል ለቢቢሲ አጋርተዋል።""",
maxLines: 10,
style: Theme.of(context)
.primaryTextTheme
.caption
.copyWith(color: Colors.black),
overflow: TextOverflow.ellipsis,
))),
Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Container(
width: 20.0,
height: 20.0,
child: Image.asset("assets/bbc.png"),
),
SizedBox(width: 8.0),
Text('ቢቢሲ - ከሁለት ሰአት በፊት',
style: Theme.of(context)
.textTheme
.caption
.copyWith(fontSize: 10.0))
],
)
],
))))
]))),
),
),
);
}
}
Try wrapping your column with 'Flexible' instead of expandable.
I had the same issue with text overflowing in column and wrapping column itself with 'flexible' allowed to make text smaller.
Flexible(
child: Padding(
padding: const EdgeInsets.only(left: 8.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Padding(
padding: const EdgeInsets.only(bottom: 8.0),
child: Text(
'Name',
style: CustomTextStyle.blueTitle14(context),
),
),
Padding(
padding: const EdgeInsets.only(bottom: 4.0),
child: Text('Long text'),
),
],
),
),
),
Based on my experiences, you should assign a fixed width to the Container containing the overflowing text, as per this post. Flutter- wrapping text .
In present version of flutter (presently 3.0) you dont have to use Flexible or Expanded as Column's child automatically expandes to fill the content of child .
For ellipses define the maxLine attribute.
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: const [
Text(
"This is very very very very very very very very very very very very very very very very very long text in Row 1 of Column",
maxLines: 2,
style: TextStyle(
backgroundColor: Colors.green, overflow: TextOverflow.ellipsis),
),
Text("This is very very long text in Row 2 of Column",
style: TextStyle(
overflow: TextOverflow.ellipsis,
backgroundColor: Colors.yellow))
],
)