Is there a way to set Height to a Drawer Header? - dart

I'm looking for a way to set the height to a Drawer Header.
I have this DrawerHeader:
DrawerHeader(
child: Text('Categories', style: TextStyle(color: Colors.white)),
decoration: BoxDecoration(
color: Colors.black
),
margin: EdgeInsets.all(0.0),
)
)
But I don't see a way to set the Height to the Drawer, that's too big.

You wrap this with a SizedBox widget.
const SizedBox(
height: 64.0,
child: DrawerHeader(
child: Text('Categories', style: TextStyle(color: Colors.white)),
decoration: BoxDecoration(color: Colors.black),
margin: EdgeInsets.all(0.0),
padding: EdgeInsets.all(0.0),
),
);

You can use SizedBox widget for resize height DrawerHeader
new SizedBox(
height : 120.0,
child : new DrawerHeader(
child : new Text('Categories', style: TextStyle(color: Colors.white)),
decoration: new BoxDecoration(color: Colors.black),
margin : EdgeInsets.zero,
padding: EdgeInsets.zero
),
);

Use SizedBox.
A Container is a heavier Widget than a SizedBox, and as bonus, SizedBox has a const constructor.

Like the previous answers, I would put my Drawer in a SizedBox. Since it is also important for me to controll where the Drawer appears, which by default should be the centerLeft, I would make the child of the box an Align with an alignment = Alignment.topLeft. See example below.
Align(
alignment: Alignment.topLeft,
child: SizedBox(
height: 300,//Your height goes here
child: Drawer(
backgroundColor: Colors.white, //Your background color goes here.
child: ListView(
children: [ ... ],
),
),
),
);

Related

fitting texts inside a stack

I have a stack contains two texts .. sometimes one of the text is really long and it will be in two lines like this:
So i tried to use FittedBox like this:
new Container(
height: 44.0,
decoration: BoxDecoration(
borderRadius: BorderRadius
.all(const Radius
.circular(30.0)),
border: new Border.all(
color:
Color(0xff606060),
width: 2.5),
),
child: new Stack(
children: <Widget>[
Align(
alignment: globals
.currentLang ==
'ar'
? Alignment
.centerRight
: Alignment
.centerLeft,
child: Padding(
padding:
EdgeInsets.only(
right: 15.0,
left: 15.0),
child: FittedBox(
fit: BoxFit
.contain,
child: Text(
),
),
),
),
Align(
alignment: globals
.currentLang ==
'ar'
? Alignment
.centerLeft
: Alignment
.centerRight,
child: Padding(
padding:
EdgeInsets.only(
left: 15.0,
right:
15.0),
child: new Text(
),
),
),
],
),
),
and i got this result:
I want a space between the two texts so it will not be covered by each other .. how to solve this?
UPDATE:
UPDATE 2:
Check this solution if it is ok for you to scale only text aligned to the right.
Container(
height: 44.0,
decoration: BoxDecoration(
borderRadius: BorderRadius.all(const Radius.circular(30.0)),
border: Border.all(color: Color(0xff606060), width: 2.5),
),
padding: EdgeInsets.all(8.0),
child: Row(
children: <Widget>[
Text('Some text'),
SizedBox(width: 8.0),
Expanded(
child: FittedBox(
fit: BoxFit.scaleDown,
child: Text(
'Demo text. Long demo text. Duplicated long demo text.',
textAlign: TextAlign.end
)
)
)
],
),
)
UPDATE:
Flex instead of Row and Expanded looks better. Check it out
Flex(
direction: Axis.horizontal,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Flexible(child: Text('10%'), flex: 0, fit: FlexFit.tight,),
SizedBox(width: 8.0),
Flexible(
flex: 1,
fit: FlexFit.loose,
child: FittedBox(
fit: BoxFit.scaleDown,
child: Text(
'Demo text. Demo text. Demo text. Demo text. Demo text.',
textAlign: TextAlign.start
),
)
)
],
)

A problem in using ClipRRect() in Flutter

I have used ClipRRect for rounded corners in the UI. The ClipRRect wraps topContent and bottomContent are a stack and a Column respectively. But, the bottom corners are not round. What may be the reason behind this?
The cardModel class is used to store the image path in this case.
class FeaturedCard extends StatelessWidget {
final FeaturedCardModel cardModel;
final double parallaxPercent;
FeaturedCard({
this.cardModel,
this.parallaxPercent = 0.0, //default value
});
#override
Widget build(BuildContext context) {
final topContent = Stack(
children: <Widget>[
Container(
padding: EdgeInsets.only(
left: 10.0,
),
height: MediaQuery.of(context).size.height * 0.3,
decoration: new BoxDecoration(
image: new DecorationImage(
image: new AssetImage(cardModel.imgUrl),
fit: BoxFit.fill,
),
)),
],
);
final bottomContentText = Text(
'This is the sample text',
style: TextStyle(fontSize: 18.0),
);
final bottomContent = Container(
height: MediaQuery.of(context).size.height * 0.5,
width: MediaQuery.of(context).size.width,
color: Colors.white,
padding: EdgeInsets.all(40.0),
child: Center(
child:
bottomContentText,
),
);
return ClipRRect(
borderRadius: BorderRadius.circular(16.0),
child: Column(
children: <Widget>[
topContent,
bottomContent,
],
),
);
}
}
If you go to Flutter Inspector and do "Toggle Debug Paint" you will see that the clipping occurs in the blue area below.
You can fix it by giving a size to your clipper.
return SizedBox(
height: MediaQuery.of(context).size.height * 0.8,
child: ClipRRect(
borderRadius: BorderRadius.circular(16.0),
child: Column(
children: <Widget>[
topContent,
//bottomContent,
],
),
),
);
The column that is the child of ClipRRect is taking as much space as it can get. so the border radius is applied to the bottom of the screen.
to solve that you just need to set mainAxisSize property of Column to MainAxisSize.min:
return ClipRRect(
borderRadius: BorderRadius.circular(16.0),
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
topContent,
bottomContent,
],
),
);

Flutter - How to control profile image size in the drawer

I would like to control the profile image size, and get it rounded instead of oval as shown below.
Changing the height and/or the width values doesn't affect neither the size nor the ratio, also the weird thing is when I change the margin parameter it changes the oval shape radius.
new UserAccountsDrawerHeader(
decoration: BoxDecoration(color: Colors.white),
currentAccountPicture: new Container(
margin: const EdgeInsets.only(bottom: 40.0),
width: 10.0,
height: 10.0,
decoration: new BoxDecoration(
shape: BoxShape.circle,
image: new DecorationImage(
fit: BoxFit.fill,
image: new NetworkImage(
"https://example.com/assets/images/john-doe.jpg",
),
),
),
),
accountName: new Container(
...
),
accountEmail: new Container(
...
),
onDetailsPressed: () {
...
},
),
What am I doing wrong ?
Update: The above way of doing is a workaround to the CircleAvatar that didn't give any control on the image size. If you tried CircleAvatar in some different way that gives control on image size, please share it to help.
Use This code for network image:
new CircleAvatar(
radius: 60.0,
backgroundColor: const Color(0xFF778899),
backgroundImage: NetworkImage("Your Photo Url"), // for Network image
),
Use this for asset Image:
new CircleAvatar(
radius: 60.0,
backgroundColor: const Color(0xFF778899),
child: new Image.asset(
'images/profile.png',
), //For Image Asset
),
If you use backgroundImage as the image provider for CircleAvatar then changing the radius property indeed has no effect. From the source circle_avatar.dart it can be observed the image is being rendered as BoxFit.cover DecorationImage(image: backgroundImage, fit: BoxFit.cover) - and in user_accounts_drawer_header.dart the currentAccountPicture is hardcoded to be a 72.0 pixel SizedBox so the image will always be 72.0px in dimensions.
https://github.com/flutter/flutter/blob/master/packages/flutter/lib/src/material/user_accounts_drawer_header.dart#L57
https://github.com/flutter/flutter/blob/master/packages/flutter/lib/src/material/circle_avatar.dart#L203
Hopefully the Flutter team adds some level of control to this in the future.
Not an answer, just more info that hopefully helps someone.
Try This:
import 'package:flutter/material.dart';
class AppDrawer extends StatefulWidget {
#override
_AppDrawerState createState() => new _AppDrawerState();
}
class _AppDrawerState extends State<AppDrawer> {
#override
Widget build(BuildContext context) {
return new Drawer(
child: Center(
child: Column(
children: <Widget>[
new UserAccountsDrawerHeader(
decoration: BoxDecoration(color: Colors.white),
currentAccountPicture: new CircleAvatar(
radius: 50.0,
backgroundColor: const Color(0xFF778899),
backgroundImage:
NetworkImage("http://tineye.com/images/widgets/mona.jpg"),
),
),
],
),
),
);
}
}
This is the screenshot of output:
Wrap your image in a CircleAvatar widget. It’s made for such purposes.
You put the margin inside the Container of the image while you have to use the margin parameter of the UserAccountDrawerHeader, this is why your image became an oval:
UserAccountsDrawerHeader(
decoration: BoxDecoration(color: Colors.white),
margin: EdgeInsets.only(bottom: 40.0),
currentAccountPicture: Container(
decoration: BoxDecoration(
shape: BoxShape.circle,
image: DecorationImage(
fit: BoxFit.fill,
image:
NetworkImage("https://via.placeholder.com/150"))),
),
accountName: new Container(
child: Text(
'Name',
style: TextStyle(color: Colors.black),
)),
accountEmail: new Container(
child: Text(
'Email',
style: TextStyle(color: Colors.black),
)),
),
You can create your own header:
DrawerHeader(
decoration: BoxDecoration(
color: Colors.blue
),
child: ListView(
children: [
return ClipRRect(
borderRadius: BorderRadius.circular(8.0),
child: Image.asset('images/myImage.jpg'),
),
//These can go here or below the header with the same background color
Text("user name"),//customize this text
Text("useremail#example.com"),
//...additional header items here
],
)),
I found a solution!!! at least thats what worked for me
import 'package:flutter/material.dart';
class HomePage extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
// Side menu
drawer: new Drawer(
child: GestureDetector(
onTap: () {},
child: ListView(
children: <Widget>[
new UserAccountsDrawerHeader(
accountName: new Text('Hymn +'),
accountEmail: new Text('johndoe#gmail.com'),
currentAccountPicture: new CircleAvatar(
backgroundImage: new NetworkImage(
'https://miro.medium.com/max/1400/1*uC0kYhn8zRx8Cfd0v0cYQg.jpeg'),
),
),
],
),
),
),
);
}
}
This works for me:
DrawerHeader(
decoration: BoxDecoration(color: Colors.blue),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
/*CircleAvatar(
radius: 50.0,
backgroundColor: const Color(0xFF778899),
child: new Image.asset('assets/images/profile_image.png'), //For Image Asset
),*/
Container(
height: 110,
child: ClipRRect(
borderRadius: BorderRadius.circular(100.0),
child: Image.asset('assets/images/profile_image.png'),
),
),
//These can go here or below the header with the same background color
//Divider(height: 1.0, thickness: 1.0, color: Colors.black),
SizedBox(height: 9.0),
Text("user name"),
//...additional header items here
],
),
),

How to make flutter TextField height match parent of container?

I want to make my TextField height the same as my container height. Please check my code below and let me know how can I make TextField match_parent of my container. I've checked this question The equivalent of wrap_content and match_parent in flutter? but I didn't find any solution. I need to make TextField to take full height and width of my container.
new Container(
height: 200.0,
decoration: new BoxDecoration(
border: new Border.all(color: Colors.black)
),
child: new SizedBox.expand(
child: new TextField(
maxLines: 2,
style: new TextStyle(
fontSize: 16.0,
// height: 2.0,
color: Colors.black
),
decoration: const InputDecoration(
hintText: "There is no data",
contentPadding: const EdgeInsets.symmetric(vertical: 40.0),
)
),
),
)
Please check the screenshot below. As said, I need my TextField to take full height of Container
Here is my solution:
Container(
height: 200,
color: Color(0xffeeeeee),
padding: EdgeInsets.all(10.0),
child: new ConstrainedBox(
constraints: BoxConstraints(
maxHeight: 200.0,
),
child: new Scrollbar(
child: new SingleChildScrollView(
scrollDirection: Axis.vertical,
reverse: true,
child: SizedBox(
height: 190.0,
child: new TextField(
maxLines: 100,
decoration: new InputDecoration(
border: InputBorder.none,
hintText: 'Add your text here',
),
),
),
),
),
),
),
It works pretty good for me. And here is a screen shot.
Answering this in 2021. There is an expands property available now. This code works:
Column(
children: [
Expanded(
child: TextField(
maxLines: null,
minLines: null,
expands: true,
),
flex: 1),
],
)
Let's remove a few lines in code and understand how flutter works.
Why we are giving height 200 to Container. Can't the Container adjust the height based on its child (in this case SizedBox.expand)
If we remove height 200, then Container occupied the entire screen because of SizedBox.expand
Do we really need the SizedBox for our use case. Let's remove that also see what happens.
Now our Container wraps the TextField. But there is some space above and below.
Who decided that space? TextField's decoration's contentPadding. Let's remove that also. It looks like below where textField wrapped by Container. Hope this is what you want. If not, please comment, we can tweak a bit and get what you want. Cheers
Final version of code which displays the above image
new Container(
// height: 200.0,
decoration: new BoxDecoration(
border: new Border.all(color: Colors.black)
),
child: new TextField(
maxLines: 2,
style: new TextStyle(
fontSize: 16.0,
// height: 2.0,
color: Colors.black
),
decoration: const InputDecoration(
hintText: "There is no data",
// contentPadding: const EdgeInsets.symmetric(vertical: 40.0),
)
),
)
Currently the only way to achieve the TextField to fill the available vertical space is:
TextField(maxLines: 1000000) //maxlines: any large int
While it is tempting to use TextField(maxLines: null), it will just set the TextField to expand with its content, until it reaches its container limit.
I think there needs to be a bool stretchVertically parameter. TextField(stretchVertically: true) would mean that the TextField will try to fill as much vertical space as it can. stretchVertically and maxLines would have to be mutually exclusive.

Flutter searchbar layout issue BoxConstraints forces an infinite width

I am trying to imitate a searchview similar to attached image, but I am getting following error. I can achieve this using ListTile but I can't set padding to the icons or TextField. So I am trying to achieve this using Row widget. Please have a look at my code and help me to draw this searchbar.
I/flutter (19181): The following assertion was thrown during
performLayout():
I/flutter (19181): BoxConstraints forces an infinite width.
I/flutter (19181): These invalid constraints were provided to
RenderAnimatedOpacity's layout() function by the
I/flutter (19181): following function, which probably computed
the invalid constraints in question:
I/flutter (19181): _RenderDecoration._layout.layoutLineBox (package:flutter/src/material/input_decorator.dart:767:11)
I/flutter (19181): The offending constraints were:
I/flutter (19181): BoxConstraints(w=Infinity, 0.0<=h<=46.0)
Here is my code:
new Container(
height: 70.0,
color: Theme.of(context).primaryColor,
child: new Padding(
padding: const EdgeInsets.all(8.0),
child: new Card(
child: new Container(
child: new Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
new Icon(Icons.search),
new Container(
height: double.infinity,
width: double.infinity,
child: new TextField(
controller: controller,
decoration: new InputDecoration(
hintText: 'Search', border: InputBorder.none),
// onChanged: onSearchTextChanged,
),
),
new IconButton(icon: new Icon(Icons.cancel), onPressed: () {
controller.clear();
// onSearchTextChanged('');
},),
],
),
)
))),
EDIT: This answer is a quick fix for the above question.
Best practice is Derek Lakin's answer
Answer:
To maximize container's width, set its width to
MediaQuery.of(context).size.width
Check this code:
new Container(
height: 70.0,
color: Theme.of(context).primaryColor,
child: new Padding(
padding: const EdgeInsets.all(8.0),
child: new Card(
child: new Container(
child: new Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
new Icon(Icons.search),
new Container(
//height: double.infinity, //This is extra
width: MediaQuery.of(context).size.width - 100.0, // Subtract sums of paddings and margins from actual width
child: new TextField(
controller: controller,
decoration: new InputDecoration(
hintText: 'Search', border: InputBorder.none),
// onChanged: onSearchTextChanged,
),
),
new IconButton(icon: new Icon(Icons.cancel), onPressed: () {
controller.clear();
// onSearchTextChanged('');
},),
],
),
)
)))
You're trying to define infinite height and width for the Container that is a parent of the TextField, which wants to use all the space.
The following works by using Expanded to fill the available space:
Container(
height: 70.0,
child: Card(
margin: EdgeInsets.all(8.0),
child: Row(
children: <Widget>[
Padding(
padding: EdgeInsets.all(8.0),
child: Icon(Icons.search),
),
Expanded(
child: TextField(
decoration: new InputDecoration(
hintText: 'Search', border: InputBorder.none),
),
flex: 1,
),
IconButton(
icon: Icon(Icons.cancel),
onPressed: () {},
)
],
),
),
),

Resources