How can I change the width of a container/card depending on screen size? - flutter

I tried adding a width to the container but it didn't do anything. By default it fills the page? Not sure what's happening. Do I have to use MediaQuery somewhere? I want the post to be the same size on both the phone and the tablet. I'm not great with explaining so I added a photo to help.
Here's my code:
body: ListView(
children: [
Container(
height: 132,
decoration: BoxDecoration(borderRadius: BorderRadius.circular(15)),
child: Card(
margin: EdgeInsets.all(10),
elevation: 8,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(15)),
child: Column(
children: <Widget>[
ListTile(
leading: CircleAvatar(
backgroundColor: Color(0xFF192A4F),
),
title: SizedBox(
height: 39,
child: TextButton(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
AutoSizeText(
'Username',
style: TextStyle(
color: Color(0xFF192A4F),
fontSize: 16,
fontWeight: FontWeight.bold),
maxLines: 2,
overflow: TextOverflow.ellipsis,
),
],
),
style: TextButton.styleFrom(
padding: EdgeInsets.zero,
minimumSize: Size(50, 30),
alignment: Alignment.centerLeft),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => SeventhRoute(),
),
);
},
),
),
),
Divider(
height: 10,
color: Colors.black26,
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
Row(
children: <Widget>[
Icon(Icons.comment_outlined,
color: Colors.black),
SizedBox(width: 8.0),
Text(
'Comment',
style: TextStyle(color: Colors.black),
),
],
),
Row(
children: <Widget>[
Icon(Icons.bookmark_outline, color: Colors.black,),
SizedBox(width: 8.0),
Text('Bookmark', style: TextStyle(color: Colors.black),),
],
),
],
),
SizedBox(
height: 12.0,
)
],
),
),
),
],
),

double width = MediaQuery.of(context).size.width;
you can get screen width from here. Then add a logic
As example if screen width of right phone is 500 and left is 1000,
then you can set
if the screen width is <= 500 ,
set the container width as screen width
otherwise
set the container width as 500.
---Additionally---
You can get screen orientation like this
var isPortrait = MediaQuery.of(context).orientation == Orientation.portrait

The reason specifying the width is ignored is because you didn't specify what should happen with the smaller card. The framework doesn't know if it should be aligned left, center, right, etc. To fix this, you can wrap your Card, Container, or even the whole ListView in a Center (or Align) widget.

Based on your images i can see that only the width is changing, height is constant, so i'd suggest in your container give width: MediaQuery.of(context).size.width;
And of course some padding to that container.

It looks like you want that widget to take as much width as it can, but no more than 500px wide. Trivial:
ConstrainedBox(
child: YourChild(...),
constraints: BoxConstraints(maxWidth: 500),
),

Related

responsive design resize problem - flutter

Widget myPost(double screenH, BuildContext context, double screenW) {
String sampleSrc =
"https://images.unsplash.com/photo-1475924156734-496f6cac6ec1?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=2070&q=80";
return Container(
margin: const EdgeInsets.symmetric(vertical: 10),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Container(
constraints: BoxConstraints(minWidth: screenW * 0.1),
height: screenH * 0.1,
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 12.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Row(
children: [
const CircleAvatar(
radius: 30,
),
SizedBox(
width: screenW * 0.01,
),
Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text(
"QWE QWE",
),
Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Text(
"27 min",
),
const Icon(
Icons.enhanced_encryption_sharp,
size: 12,
),
],
),
],
),
],
),
const Icon(Icons.more_vert_sharp),
]),
),
),
ReadMoreText(
"text" * 800,
trimCollapsedText: "Read More...",
trimExpandedText: "Read less",
trimLines: 3,
style: const TextStyle(fontSize: 20),
trimMode: TrimMode.Line,
moreStyle: const TextStyle(
color: Colors.black,
fontWeight: FontWeight.bold,
),
lessStyle: const TextStyle(
color: Colors.black,
fontWeight: FontWeight.bold,
),
),
InkWell(
onTap: () {},
child: Container(
constraints: BoxConstraints.loose(Size.fromHeight(screenH * 0.5)),
child: Image.network(
sampleSrc,
fit: BoxFit.fitWidth,
width: double.infinity,
),
),
),
],
),
);
}
My design
I'm using the responsive_framework package, but when I reduce the height, all the widgets resizing, and I get overflows. The design I'm trying to make is like the following GIF the design that I want
Just like in responsive sites, I want the widgets to be fixed and only scrollable, no matter how much the height decreases.
Any trick or document to do this ?
The overall height on shrink is greater than height: screenH * 0.1, you can include extra pixels like height: 10+ (screenH * 0.1) But you can just include fixed height here. Like on item, you can choose minimum fixed height like 64, and you don't to have to worry about making larger. You can also check your attached GIF row height doesn't change.
Second option is wrapping Text with FittedBox widget, or using auto_size_text.

How to set width as much as I need, but not more

In appBar I have a container which is responsible for displaying text (it could be 5 chars or even 100). And I want to adjust width of container based on text. For example for 5 chars container should show text and should be a little bigger than text (I will add paddings later), but for 100 chars container should take all possible space and show text with dots.
Currently I have two solutions:
The first one (Without spacer() in tree) is expanding container always to the biggest possible width (like I said, I don't need this big container for short texts)
The second one (with spacer() in tree) is always displaying container with 1/3 width of appbar (Did someone know why it's always the same width? It's kind of interesting).
return Scaffold(
appBar: AppBar(
titleSpacing: 10,
centerTitle: false,
automaticallyImplyLeading: false,
title: SizedBox(
width: MediaQuery.of(context).size.width,
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Container(height: 40, width: 40, color: Colors.amberAccent),
const SizedBox(width: 10),
const Text("Some Text"),
const SizedBox(width: 10),
Expanded(
child: Container(
color: Colors.purpleAccent,
height: 40,
child: const Center(
child: Text(
"text",
overflow: TextOverflow.ellipsis,
softWrap: true,
),
),
),
),
],
),
),
),
body: Container(),
);
So, how can I adjust width of this container to text inside?
Update:
I don't know if I explained it correctly, because your answers weren't related with my question 😁 So I will try again:
I want the last one container to take full possible width if text is long and for shorten texts just width to cover background behind text.
Here is long text: (It should be like that)
Here is short text: (Container should be smaller)
You should use constraints: BoxConstraints(maxWidth:), property of Container.
Please go with below code.
Container(
color: Colors.red,
padding: const EdgeInsets.all(20.0),
constraints: BoxConstraints(
maxWidth: MediaQuery.of(context).size.width * 0.7,
),
child: Text('Hello', style: TextStyle(color: Colors.black)),
),
Spacer(),
Flexible(
child: Container(
color: Colors.purpleAccent,
height: 40,
child: const Center(
child: Text(
"Long Textttttttttttttttttttt",
overflow: TextOverflow.ellipsis,
softWrap: true,
),
),
),
),
Your result will be like below screenshot.
I implement another text for checking dynamic width of container.
Container(
color: Colors.red,
padding: const EdgeInsets.all(20.0),
constraints: BoxConstraints(
maxWidth: MediaQuery.of(context).size.width * 0.7,
),
child: Text('Hello World', style: TextStyle(color: Colors.black)),
),
Spacer(),
Flexible(
child: Container(
color: Colors.purpleAccent,
height: 40,
child: const Center(
child: Text(
"Long Textttttttttttttttttttt",
overflow: TextOverflow.ellipsis,
softWrap: true,
),
),
),
),
For This You can Use :
Flexible Widget:
Example:
Flexible(
child: Container(
color: Colors.green,
)
),
or Wrap Widget :
Example :
Card(
margin: const EdgeInsets.only(top: 20.0),
child: Padding(
padding: const EdgeInsets.all(20.0),
child: Column(
children: <Widget>[
Text(
'Categories',
style: TextStyle(fontFamily: 'MonteSerrat', fontSize: 16.0),
),
Wrap(
children: <Widget>[
_checkBox('Gaming'),
_checkBox('Sports'),
_checkBox('Casual'),
_checkBox('21 +'),
_checkBox('Adult'),
_checkBox('Food'),
_checkBox('Club'),
_checkBox('Activities'),
_checkBox('Shopping')
],
)
],
),
));

Flutter & AlertDialog : How to stretch a container so that it has the same width with the AlertDialog box?

I have been trying to make a button in AlertDialog box in Flutter. But I cannot find a way to stretch the button container. Please check my code and see the example picture below.
AlertDialog(
title: Center(child: Text("Picture")),
content: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Container(
width: width,
//height: height,
child: FadeInImage.memoryNetwork(
placeholder: kTransparentImage,
image: image.url,
),
),
SizedBox(
height: 10,
),
InkWell(
onTap: () {
Navigator.pop(context);
},
child: Container(
alignment: Alignment.center,
height: 50,
width: width,
color: primaryColor,
child: Text(
'Okay',
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold),
),
),
),
],
),
);
Please help me in this. I am looking forward to hearing your opinion. Thank you in advance.
The AlertDialog has a default content padding of 24 logical pixels to the right, left and bottom of the AlertDialog to separate the content from the other edges of the dialog..
To Make the Button fit the AlertDialog width, you will need to give the AlertDialog a padding of zero and apply paddings to others widgets except the Button.
I added an example using your code:
AlertDialog(
// change the default padding to zero
contentPadding: EdgeInsets.zero,
title: Center(child: Text("Picture")),
content: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
// wrap your container with a padding widget
Padding(
padding: const EdgeInsets.all(20.0), // give a preferred padding
child: Container(
width: width,
//height: height,
placeholder: kTransparentImage,
image: image.url,
),
),
),
SizedBox(
height: 10,
),
InkWell(
onTap: () {
Navigator.pop(context);
},
child: Container(
alignment: Alignment.center,
height: 50,
width: width,
color: primaryColor,
child: Text(
'Okay',
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold),
),
),
),
],
),
);

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.