Label(text) at the bottom side of image in flutter - flutter

I have a custom build widget for grid view, in which i am either sending Icon or image to display along with Text (label). Now when i send icon i can display the test below icon, but when i am trying image i am not sure if the below approach is correct to display text or not, i am trying to put EdgeInsets in the container. I think it might fail due to pixel overload, but in my emulator, it seems to be fine.. Is there any better option for this scenario or the approach I am following is ok?
if (image != null) ...[
Container(
margin: EdgeInsets.only(top:150.0),
),
] else ...[
child ?? Container(),
],
Text('$label',
style: TextStyle(
color: AppColors.lightBlue,
fontSize: 20,
),),

If I am getting your problem well, then the solution is to use Alignment Class Flutter, in the Container. What this will do, is it allows the child of the Container to be aligned the way we want to align it. Since your requirement is to align the text at the bottom center, hence we would use the Alignment property, Alignment.bottomCenter.
Please Note: This will tell you how to align the content which will not be disturbed as per the device size, with a background image
SOLUTION 1 [EFFICIENT]
Container(
height: MediaQuery.of(context).size.height * 0.3, // ignore this, cos I am giving height to the container
width: MediaQuery.of(context).size.width * 0.5, // ignore this, cos I am giving width to the container
decoration: BoxDecoration(
image: DecorationImage(
fit: BoxFit.cover,
image: NetworkImage('https://i.pinimg.com/originals/0c/96/b1/0c96b19dc89ffdaa7ff737cfc04a095f.png')
)
),
alignment: Alignment.bottomCenter, // This aligns the child of the container
child: Padding(
padding: EdgeInsets.only(bottom: 10.0), //some spacing to the child from bottom
child: Text('Hello', style: TextStyle(color: Colors.white, fontWeight: FontWeight.bold))
)
)
The output would look like this now:
You can check this piece of code in any of the device, and it will show up just fine.
SOLUTION 2 [NOT RECOMMENDED]
Now, if you really want the margin, there is a cleaner way to do it, and that is using MediaQuery, as you can see in the above code also for giving out height and width.
Now, the question arises, what MediaQuery is, you can find it here, or in a simpler statement, it takes care of the size of the device. Now, whenever, we are concerned about the size of the device with the content alignment, we can use MediaQuery, and what it does, is it will adjust the margin/height/width/padding etc according to the Device size, and will look the same everywhere
How we can do that, I will just use your code only, and since you want the text to come at the bottom with the use of margin. Here, how you can do that
Container(
height: MediaQuery.of(context).size.height * 0.3,
width: MediaQuery.of(context).size.width * 0.5,
decoration: BoxDecoration(
image: DecorationImage(
fit: BoxFit.cover,
image: NetworkImage('https://i.pinimg.com/originals/0c/96/b1/0c96b19dc89ffdaa7ff737cfc04a095f.png')
)
),
child: Container(
margin: EdgeInsets.only(top: MediaQuery.of(context).size.height * 0.25),
child: Text('Hello', textAlign: TextAlign.center, style: TextStyle(color: Colors.white, fontWeight: FontWeight.bold))
)
)
OUTPUT
MediaQuery.of(context).size.height = device height, and when we multiply, it does the math according to the device, and align the content. Similarly for MediaQuery.of(context).size.width= device width
I would suggest SOLUTION 1 only, since it is clean, and would not let you do a lot in nested child. I hope that clears your doubt. Let me know. Thanks :)

Related

Text Overflow inside container creating design such as messenger messages in which text is inside container in which height and width not mentioned

I want container to maintain its height and width according to the text without the text overflowing such as if there is small text width is small but if text is long then width takes up size as possible and rest goes to next Line. Please help
Container(
padding: EdgeInsets.symmetric(vertical: 10, horizontal: 15),
child: Text(
message.text,
style: TextStyle(
color: message.isSender
? Colors.white
: Theme.of(context).textTheme.bodyText1?.color,
),
),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(40),
color: KprimaryColor.withOpacity(message.isSender ? 1 : 0.1)),
),
Set width to your container, I think it should fix the problem
You have to Wrap it with Expanded or Flexible it will stretch the width and height
Note: Flexible must be used under the following Widgets Row,Column,Stack.

My text is overflowing Pixels, how can I fix that and how do I increase the size of image

I have tried using Expanded and Flexible and none of it is working.I am not able to understand why.Also is this the best way to increase the size of image, because I want that my images looks size looks same across all devices.
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Container(
width: size.width * 0.4,
height: size.width * 0.6,
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage('images/brushOne.jpg'),
fit: BoxFit.fill)),
),
Padding(
padding: const EdgeInsets.only(top: 40.0),
child: Text(
'Thank you for letting me do what I love, your support is contagious If I could put all 10,000 of you in a room and give you all a hug I WOULD. Your support makes my heart grow and glow. Thank you for helping me create a business and a family.I love you all 🌈',
),
),
],
)
Row(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Container(
width: MediaQuery.of(context).size.width * 0.4,
height: MediaQuery.of(context).size.width * 0.6,
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage('assets/images.jpg'),
fit: BoxFit.fill)),
),
Container(
child: Container(
padding: EdgeInsets.only(top: 40),
child: Text(
'Thank you for letting me do what I love, your support is contagious If I could put all 10,000 of you in a room and give you all a hug I WOULD. Your support makes my heart grow and glow. Thank you for helping me create a business and a family.I love you all 🌈',
),
width: MediaQuery.of(context).size.width * 0.6,
),
),
],
)
You set the first container to 40%.
width: MediaQuery.of(context).size.width * 0.4
If you set the width of the second container to 60%,
width: MediaQuery.of(context).size.width * 0.6
the problem will be solved. You can use sizedbox() to leave space between two containers if you want.
Wrap the padding widget fixed the problem:
The difference is the constraints passed to Text.
With Expanded, the constraints is fixed size:
Without Expanded, the constraints is infinity:
I suggest you to use ,
SizedBox(
width: 100,
child: Text(
"Thank you for letting me do what I love, your support is contagious If I could put all 10,000 of you in a room and give you all a hug I WOULD. Your support makes my heart grow and glow. Thank you for helping me create a business and a family.I love you all 🌈",
maxLines: 5,
overflow: TextOverflow.ellipsis,
),
),
Expanded should work as demoed in this quick mock-up here.
Like Engin has mentioned MediaQuery is your best bet for scaling contents to a device's screen, but if you're applying MediaQuery to both sections of the Row, you'll have to update both sizes each time you choose to resize one element. This is accruing unnecessary technical debt that will compound if you ever choose to add additional elements to the Row in the future. Expanded on the other hand will take up the remaining space without the need to manually calculate sizes each time you make a change to UI elements.

How do I give a container a preferred height that can later be changed?

This is my Container:
Container(
height: height - height * 0.4, //this is my preferred height.
width: width - width * 0.7,
decoration: decoration,
child: Padding(
padding: const EdgeInsets.symmetric(vertical: 25.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
Image.asset(
'assets/opensource.png',
scale: 1.35,
),
text('Open Source Software', 20, Color(0xFF02bbe5)),
text('Contributor since December, 2020', 16,
Color(0xFF02bbe5)),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 20.0),
child: text(
'test',
16,
Colors.blueGrey),
),
],
),
),
),
I need to make the app responsive, for that the Container needs to be elongated when the inner widgets don't fit inside the Container properly.
How do I give a preferred height to this Container but also allow it to resize freely in case of overflow?
Note: This Container is inside a Column itself with SingleChildScrollView as the parent. And I am building a web app.
Edit: I have used MediaQuery for getting width and height.
There are multiple ways to approach this problem. You can wrap you container inside an AspectRatio widget and an Expanded.
AspectRatio(
aspectRatio: someAspectRatioValue,
child: Expanded(
child Container(...)
)
)
This should expand the items container without loosing shape of the container.
You can also build your whole screen with a LayoutBuilder, though that would require a lot of reworking.
If you want to make your application responsive in Flutter then you should Sizer package( Here ). This package will make your app responsive for any screen size, it divides into percentages. For ex:
Container(
width: 20.w, //It will take a 20% of screen width
height:30.h //It will take a 30% of screen height
)

Connect a row of circles to a chain in Flutter

I have a rather easy problem, but which I cannot seem to solve efficiently.
So I have a row of a changing number of Containers with a centered Circle, for which I used a circle icon from the Font Awesome package. And what I want to do is to connect the sides of these circles so that they form a chain.
I though of creating a custom icon, a circle with a line to the side long enough to reach the next circle.
Another option would be to use Stack and manually place a line between the cirlces, but because the number of cicles is changing, I fear the that the line will overflow the circle boundries.
Any of ou have an idea how to solve this efficiently?
Edit:
So here is a picture of what I want it to be like:
Picture of the Chain
My Code right now is just
Row(
children: <Widget>[
Container(
child: Center( child: CircleIcon ),
),
Container(
child: Center( child: CircleIcon ),
), ...
You can just use Container for this. Really simple with Container.
Container{
height: 50, // give any height you need
width: 50, // give the same as height,
decoration: BoxDecoration(
shape: BoxShape.circle,
border: Border.all(
color: Colors.black
),
),
}

Different results when run on different screen sizes

I'm getting different results of the same screen when run on different phone sizes:
The second phone screen is my desired outcome. Using expanded initially helped me solve an issue with the first phone screen (where there was an extra space below the green bar). Later I realized that I was getting overflow on the second phone screen. Thus, I solved the overflow by using SingleChildScrollView. However that somehow cause the first phone screen to have the issue of the extra space again.
Code:
final quizBottomContentText = Container(
width: MediaQuery.of(context).size.width,
padding: EdgeInsets.only(left:30.0, right:30.0, top: 30.0, bottom: 30),
child: Text(
questions[questionNum].title,
style: TextStyle(fontSize: 18.0),
)
);
final quizOptions = Container(
width: MediaQuery.of(context).size.width,
padding: EdgeInsets.only(bottom: 20.0),
child: Center(
child: Column(
children: questions[questionNum].options.map<Widget>(
(option) => SimpleRoundButton(
backgroundColor: Color.fromRGBO(58, 66, 86, 1.0),
buttonText: Text(option,
style: TextStyle(
color: Colors.white
),
),
textColor: Colors.white,
onPressed: (){},
),
).toList(),
)
)
);
final countdown = CountdownWidget(
width: MediaQuery.of(context).size.width,
duration: 20,
triviaState: triviaState,
);
final quizBottomContent = Expanded(
child: SingleChildScrollView(
child: Container(
width: MediaQuery.of(context).size.width,
child: Column(
children: <Widget>[quizBottomContentText, quizOptions, countdown],
),
)
)
);
Because you're app is not responsive. See, you're passing size in a hard coded way
eg: padding: EdgeInsets.only(bottom: 20.0)
What this means? Mean that in your emulator, you'll get a result, maybe is what you expect, but in another device, maybe in a iPhone Xs Max, the result is diferent, so, what can you do?
You'll have two options here, the first, use the MediaQuery component. I'll show you how and why I use the way I use for a better understanding.
In Flutter, we have the MediaQuery component with a lot of propierty, one of them, is this: MediaQuery.of(context).size.width (Which gets your device's full width size). Everything fine till here, right? If you print this in diferent devices, you'll get diferente results, which means that a Padding with 20 from left/right will be different in both devices.
I made a calculation to kinda ''hack'' this and make it responsive, get this:
MediaQuery.of(context).size.width and divide by 400. Why 400? Me and a friend discovered this and when we divided, we've got a value almost next to 1 in very different devices, so, if you get the result (eg 1.5) and multiplies by 20, you'll make your app kinda of responsive. It's a way, the second way it's to use the LayoutBuilder which need a context and a constraints as parameters.
With constraints, you can manipulate to show differents model designs in differents devices, like, buildConventionalDesig for devices with width less than 400, an example, or buildBiggerDesign for a bigger phone, like iPhone Xs Max.
There's an article that you could be your reference to help you, check it:
Build Response UIs in Flutter. It doesn't cover this trick with MediaQuery, but maybe you can get a new insight.
Hope this have helped.