I am very new to flutter development. Currently learning Row, Column, Expanded UI stuffs. I want the row to be in this fashion Image of Row I need to achieve and this is what I am getting currently Output of my code, this is my code :`
Widget drawerTiles(String tileIcon, String tileText, IconData tileRightIcon) {
return Padding(
padding: const EdgeInsets.only(top: 20, left: 16, right: 32.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
CircleAvatar(
radius: 14,
backgroundColor: Hexcolor('#0565ac'),
child: Padding(
padding: EdgeInsets.all(0),
child: SvgPicture.asset(
tileIcon,
color: Colors.white,
),
),
),
Text(
tileText,
style: TextStyle(
fontSize: 12, fontWeight: FontWeight.w600, color: Colors.black),
),
Icon(tileRightIcon)
],
),
);
}
`
It is a custom widget as you can see and I am passing the necessary parameters for it. The issue is with alignment probably. How do I solve this?
you can achieve that easily using ListTile widget
ListTile widget
Related
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,
);
}
}
I want to align my some widgets in a row in a particular way. I want the Icon to be at the beginning of the row and the text to be at the center, I tried wrapping the text widget in a center widget but that didn't work. Please how can I carry out something like that with a row that only has two children?
Wrap the Center in an Expanded. So something like this:
Widget build(BuildContext context) {
return Row(children: const [
Icon(Icons.abc),
Expanded(child: Center(child: Text('abc')))
]);
}
You could use a Stack for the same
Sample code
Container(
padding: const EdgeInsets.symmetric(vertical: 18),
color: Colors.black,
child: Stack(
children: const [
Center(
child: Text(
"Login",
style: TextStyle(fontSize: 18, color: Colors.white,fontWeight: FontWeight.w600),
),
),
Positioned(
left: 12,
child: Icon(
Icons.close,
color: Colors.white,
),
),
],
),
);
I am trying to make my app responsive and I noticed that there is a problem in some screen sizes , I'm already using Expanded for the Container that including the question
And I tried using Expanded for Answers too and flex: 2; for the question and that's what I got
appPic2
What it should be like
Expanded(
child: Container(
width: double.infinity,
height: 220.0,
margin: EdgeInsets.only(
top: 5, bottom: 0, left: 30.0, right: 30.0),
padding: EdgeInsets.symmetric(
horizontal: 0.0, vertical: 0.0),
child: Center(
child: Column(
children: [
Text(
_questions[_questionIndex]['question'],
textDirection: TextDirection.rtl,
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 20.0,
fontFamily: "Tajawal",
color: Colors.white,
fontWeight: FontWeight.w400,
),
),
Answer Code
...(_questions[_questionIndex]['answers']
as List<Map<String, Object>>)
.map(
(answer) =>
Answer(
answerText: answer['answerText'],
answerColor: answerWasSelected
? answer['score']
? Colors.green[400]
: Colors.red[400]
: null,
),
and this is for answer in another file
InkWell(
onTap: answerTap,
child: Container(
padding: EdgeInsets.all(15.0),
margin: EdgeInsets.symmetric(vertical: 5.0, horizontal: 30.0),
width: double.infinity,
child: Text(
answerText,
),
),
),
);
i think the problem is you providing a height for the container which has the text as a child
and the text is long
so if you want the container to be with fixed height then you should wrap the column widget with singleChildScrollView
or if you want the container to take the question space , then remove the height property from the container and wrap the column with Expanded
Add
mainAxisSize: MainAxisSize.min
To the column widget. Now the column has no bounds
How to do like this
image
code
Row(
children: [
SizedBox(width: 33.w),
Text(
StringRes.getStart,
style: TextStyle(
fontWeight: FontWeight.w500,
color: AppColors.backgroundColor,
fontSize: 13.sp,
),
),
Spacer(),
Icon(
Icons.arrow_forward,
color: AppColors.backgroundColor,
),
SizedBox(
width: 3.w,
),
],
),
i get diffrent diffrent spacing in diffrent device
like this image 2
image 3
I assume what you are looking for is something like this:
Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: const [
SizedBox(width: 20),
Text('Get started'),
SizedBox(
width: 20,
child: Icon(Icons.arrow_forward),
),
],
),
),
In this example, the Text widget is centered by having equally large SizedBox widgets on both sides of it and by telling the Row widget to use MainAxisAlignment.spaceBetween. The padding around the Row contents is achieved with the Padding widget, so that it does not interfere with the content alignment.
I hope this helps you.
I'm building a product detail page. As the following piece of code and image shown, when there is a lot of content in the description part, the bottom overflow will occur. I'm wondering how to make the page scrollable, I've tried wrapping the Stack with SingleChildScrollView, but this is definitely not working in my case here. Can anyone help me with that? Thank you very much!!!!!
class DetailsScreen extends StatelessWidget {
#override
Widget build(BuildContext context) {
final size = MediaQuery.of(context).size;
return Scaffold(
backgroundColor: Colors.white,
body: Stack(
children: [
buildBody("path/to/image", size),
],
),
);
}
Positioned buildBody(String imagePath, Size size) {
return Positioned.fill(
child: Column(
children: [
Expanded(
child: Container(
padding: EdgeInsets.symmetric(vertical: 60, horizontal: 30),
color: Colors.green,
child: Stack(
children: [
Align(
alignment: Alignment.center,
child: Hero(
tag: 1,
child: Image.asset(
imagePath,
width: size.width * 0.7,
),
),
),
],
),
),
),
Expanded(
child: Container(
color: Colors.white,
child: Column(
children: [
SizedBox(
height: 100,
),
Container(
margin: EdgeInsets.symmetric(
horizontal: 20,
),
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
CircleAvatar(),
SizedBox(
width: 10,
),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Anvesha Shandilya',
style: TextStyle(
fontWeight: FontWeight.bold, fontSize: 16),
),
Text(
'Owner',
style: TextStyle(
color: fadedBlack,
),
),
],
),
Expanded(child: Container()),
Text(
'Dec 16, 2020',
style: TextStyle(
color: fadedBlack,
fontSize: 12,
),
),
],
),
),
SizedBox(
height: 30,
),
Container(
margin: EdgeInsets.symmetric(
horizontal: 20,
),
child: Text(
'A lot of content..................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................',
style: TextStyle(
color: fadedBlack,
height: 1.7,
),
),
),
],
),
),
),
],
),
);
}
}
Error: Bottom Overflowed
To reproduce: Change the path/to/image, to this: A image can be used with the code:
tl;dr remove Expanded widgets -> remove Stack -> replace Column with ListView (for scrollability)
Start by removing Expanded widgets from the tree as you don't really need them. If possible, you should use mainAxisAlignment and crossAxisAlignment to position your widgets. That's exactly how you should handle placing the date next to user's name.
Expanded documentation states with which widgets you can use it:
Creates a widget that expands a child of a Row, Column, or Flex so
that the child fills the available space along the flex widget's main
axis.
Then remove Stack widget. If you don't then it will still work as Stack tries to get as big as its positioned children so it will just get as big as the Column you have inside. It's redundant.
Last but not least, replace Column with ListView. Column doesn't really care about whether it's overflowing or if it's being rendered. So if you create a Column that is bigger than the screen, it will simply display it which will cause the overflow. To fix that you could wrap it SingleChildScrollView, but I think it's more appropriate to just use ListView instead.
Here's an amazing explanation of layout system in Flutter: https://flutter.dev/docs/development/ui/layout/constraints