Related
This is my app bar with one line text:
appBar: AppBar(
title: Text("Summer Trip"),
centerTitle: true,
actions: [
PopupMenuButton(
itemBuilder: (context){
return [
PopupMenuItem<int>(
value: 0,
child: Text("Test"),
),
];
},
),
],
),
And it gives the following result:
As you see the center of the row is about 25 pixels from screen border.
Now I need to add the second line to my title. This is my solution:
appBar: AppBar(
toolbarHeight: 70,
flexibleSpace: SafeArea(
child: Center(
child: Column(
children: [
Padding(
padding: const EdgeInsets.only(top: 10),
child: Text('Summer Trip',
style: TextStyle(color: Colors.white, fontWeight: FontWeight.w500, fontSize: 20.0)
),
),
Padding(
padding: const EdgeInsets.only(top: 5),
child: Text('Step 1',
style: TextStyle(color: Colors.white54, fontWeight: FontWeight.normal, fontSize: 14.0)
),
),
],
),
),
),
actions: [
PopupMenuButton(
itemBuilder: (context){
return [
PopupMenuItem<int>(
value: 0,
child: Text("Test"),
),
];
},
),
],
),
And this is the result:
As you see, if we increase toolbarHeight of AppBar then arrow and menu buttons move down. However, I need them to stay at the same position. Could anyone say how to do it?
You can wrap your widgets with Align widget.
appBar: AppBar(
toolbarHeight: 70,
flexibleSpace: SafeArea(
child: Center(
child: Column(
children: const [
Padding(
padding: EdgeInsets.only(top: 10),
child: Text('Summer Trip',
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.w500,
fontSize: 20.0)),
),
Padding(
padding: EdgeInsets.only(top: 5),
child: Text(
'Step 1',
style: TextStyle(
color: Colors.white54,
fontWeight: FontWeight.normal,
fontSize: 14.0),
),
),
],
),
),
),
leading: Align(
alignment: Alignment.topCenter,
child: IconButton(
onPressed: () {},
icon: const Icon(
Icons.arrow_back,
),
),
),
actions: [
Align(
alignment: Alignment.topCenter,
child: PopupMenuButton(
itemBuilder: (context) {
return [
const PopupMenuItem<int>(
value: 0,
child: Text("Test"),
),
];
},
),
),
],
),
Output:
Thanks to #Pavel_K for correcting me, earlier I misunderstood the question.
Corrected Answer
Instead of using flexibleSpace, use title (for the main title) and bottom (for the subtitle). This approach will solve your query, and make the icons stay on top (along the center of the title).
appBar: AppBar(
centerTitle: true,
toolbarHeight: 70,
leading: const Icon(Icons.arrow_back),
title: Column(
children: const [
Text(
'Summer Trip',
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.w500,
fontSize: 20.0,
),
),
],
),
bottom: const PreferredSize(
preferredSize: Size(0, 14),
child: Padding(
padding: EdgeInsets.only(bottom: 8),
child: Text(
'Step 1',
style: TextStyle(
color: Colors.white54,
fontWeight: FontWeight.normal,
fontSize: 14.0,
),
),
),
),
actions: [
PopupMenuButton(
itemBuilder: (context) {
return [
const PopupMenuItem<int>(
value: 0,
child: Text("Test"),
),
];
},
),
],
),
Old (incorrect) Answer
I think you are using the flexibleSpace with the incorrect intent; it is meant to be used with FlexibleSpaceBar.
What you want to achieve can be simply achieved using title property of AppBar, and it will center the icon on it's own.
It will look like this:
appBar: AppBar(
centerTitle: true,
toolbarHeight: 70,
leading: const Icon(Icons.arrow_back),
title: Column(
children: const [
Padding(
padding: EdgeInsets.only(top: 10),
child: Text(
'Summer Trip',
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.w500,
fontSize: 20.0,
),
),
),
Padding(
padding: EdgeInsets.only(top: 5),
child: Text(
'Step 1',
style: TextStyle(
color: Colors.white54,
fontWeight: FontWeight.normal,
fontSize: 14.0,
),
),
),
],
),
),
Hi what I want to do is make a dropdown menu inside of a drawer header but when I tried I got constraint errors also Im curious how can I pass 2 values into it so when pressed the text will change according to it
My code:
return Drawer(
child: ListView(
padding: EdgeInsets.zero,
children: [
Container(
height: MediaQuery.of(context).size.height * 0.20,
child: DrawerHeader(
decoration: BoxDecoration(
color: Colors.blue,
),
child: Padding(
padding: const EdgeInsets.all(15.0),
child: Row(
children: [
Expanded(
child: Align(
alignment: Alignment.centerLeft,
child: Column(
children: [
Align(
alignment: Alignment.centerLeft,
child: Text(
widget.name,
style: TextStyle(
color: Colors.amber,
fontSize: 16,
fontWeight: FontWeight.w500,
),
),
),
SizedBox(
height: 3,
),
Align(
alignment: Alignment.centerLeft,
child: Text(
widget.name,
style: TextStyle(
color: Colors.white,
fontSize: 14,
fontWeight: FontWeight.w400,
),
),
),
],
),
),
),
Expanded(
child: Align(
alignment: Alignment.centerRight,
child: Icon(Icons.keyboard_arrow_down),
),
)
],
),
),
),
),
SingleChildScrollView(
child: Column(
children: [
AppListItems(Icons.favorite, 'Text', SecondRoute()),
AppListItems(Icons.favorite, 'Text', SecondRoute()),
],
),
),
],
),
);
This is how it looks like and where I want the dropdown menu to be:
Any help would be great, thanks in advance
Try below code hope its help to you.
drawer: Drawer(
child: ListView(
padding: EdgeInsets.zero,
children: [
Container(
height: MediaQuery.of(context).size.height * 0.20,
child: DrawerHeader(
decoration: BoxDecoration(
color: Colors.blue,
),
child: Padding(
padding: const EdgeInsets.all(15.0),
child: Row(
children: [
Expanded(
child: Align(
alignment: Alignment.centerLeft,
child: Column(
children: [
Align(
alignment: Alignment.centerLeft,
child: Text(
'widget.name',
style: TextStyle(
color: Colors.amber,
fontSize: 16,
fontWeight: FontWeight.w500,
),
),
),
SizedBox(
height: 3,
),
Align(
alignment: Alignment.centerLeft,
child: Text(
'widget.name',
style: TextStyle(
color: Colors.white,
fontSize: 14,
fontWeight: FontWeight.w400,
),
),
),
],
),
),
),
Expanded(
child: DropdownButton<String>(
value: dropdownValue,
isDense: true,
icon: const Icon(Icons.arrow_downward),
elevation: 16,
style: const TextStyle(color: Colors.deepPurple),
underline: Container(
height: 2,
color: Colors.deepPurpleAccent,
),
onChanged: (String? newValue) {
setState(() {
dropdownValue = newValue!;
});
},
items: <String>['One', 'Two', 'Free', 'Four']
.map<DropdownMenuItem<String>>((String value) {
return DropdownMenuItem<String>(
value: value,
child: Text(value),
);
}).toList(),
),
)
],
),
),
),
),
SingleChildScrollView(
child: Column(
children: [
Icon(
Icons.favorite,
),
Icon(
Icons.favorite,
),
],
),
),
],
),
),
Your result screen->
Your dropdown->
As you can see in the UI, when I am using text and textformfield in column, the space between Mobile number and TextFormField is too much -
I am making a UI, in which I want things to be like this -
So I used two different approaches. First, I used label in the TextFormField, but whenever TextFormField is not active, it look like this -
And when it is active, it looks perfectly as I want -
So, how can I achieve this, that whenever the field is not active, it should still look like this with label text or how to reduce the padding to remove the white space when using a column with text and textfield as the children.
Refer to the code here -
class HelpPage extends StatelessWidget {
#override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
appBar: AppBar(
title: Text('Help'),
backgroundColor: colorPrimary,
centerTitle: true,
),
body: Column(
children: [
ListTile(
title: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'PNR/Booking Id',
style: TextStyle(
color: popUpLightTextColor,
),
),
Text(
'AWP80A',
style: TextStyle(
fontSize: 16.0
),
),
],
),
Column(
children: [
Text(
'Seats',
style: TextStyle(
color: popUpLightTextColor,
),
),
Text(
'UD8',
),
],
),
],
),
),
Padding(
padding: const EdgeInsets.symmetric(vertical: 4.0),
child: Container(
height: 1.0,
width: double.infinity, //MediaQuery.of(context).size.width,
color: Colors.grey[300],
),
),
ListTile(
title: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Origin',
style: TextStyle(
color: popUpLightTextColor,
),
),
Text(
'New Delhi',
style: TextStyle(
fontSize: 16.0
),
),
],
),
Column(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
Text(
'Destination',
style: TextStyle(
color: popUpLightTextColor,
),
),
Text(
'Mathura',
),
],
),
],
),
),
Padding(
padding: const EdgeInsets.symmetric(vertical: 4.0),
child: Container(
height: 1.0,
width: double.infinity, //MediaQuery.of(context).size.width,
color: Colors.grey[300],
),
),
ListTile(
title: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Name*',
style: TextStyle(
color: popUpLightTextColor,
),
),
Text(
'Kirti Agarwal',
style: TextStyle(
fontSize: 16.0
),
),
],
),
),
Padding(
padding: const EdgeInsets.symmetric(vertical: 4.0),
child: Container(
height: 1.0,
width: double.infinity, //MediaQuery.of(context).size.width,
color: Colors.grey[300],
),
),
ListTile(
title: Container(
width: MediaQuery.of(context).size.width*0.7,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
/*Text(
'Mobile Number*',
style: TextStyle(
color: popUpLightTextColor,
),
),*/
TextFormField(
decoration: InputDecoration(
border: InputBorder.none,
label: Text('Mobile Number*', style: TextStyle(color: Colors.black, fontWeight: FontWeight.w500, fontSize: 20),)
),
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 17,
),
),
],
),
),
),
Padding(
padding: const EdgeInsets.only(top: 4.0),
child: Container(
height: 1.0,
width: double.infinity, //MediaQuery.of(context).size.width,
color: Colors.grey[300],
),
),
ListTile(
title: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Origin',
style: TextStyle(
color: popUpLightTextColor,
),
),
Text(
'New Delhi',
style: TextStyle(
fontSize: 16.0
),
),
],
),
Column(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
Text(
'Destination',
style: TextStyle(
color: popUpLightTextColor,
),
),
Text(
'Mathura',
),
],
),
],
),
),
Padding(
padding: const EdgeInsets.symmetric(vertical: 4.0),
child: Container(
height: 1.0,
width: double.infinity, //MediaQuery.of(context).size.width,
color: Colors.grey[300],
),
),
ListTile(
title: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Origin',
style: TextStyle(
color: popUpLightTextColor,
),
),
Text(
'New Delhi',
style: TextStyle(
fontSize: 16.0
),
),
],
),
Column(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
Text(
'Destination',
style: TextStyle(
color: popUpLightTextColor,
),
),
Text(
'Mathura',
),
],
),
],
),
),
Padding(
padding: const EdgeInsets.symmetric(vertical: 4.0),
child: Container(
height: 1.0,
width: double.infinity, //MediaQuery.of(context).size.width,
color: Colors.grey[300],
),
),
],
),
),
);
}
}
try with content padding textformfield content padding
TextFormField(
decoration: InputDecoration(
border: InputBorder.none,
contentPadding: EdgeInsets.symmetric(vertical: 5), // adjust as you need
label: Text('Mobile Number*', style: TextStyle(color: Colors.black, fontWeight: FontWeight.w500, fontSize: 20),)
),
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 17,
),
),
output:
I have a piece of code here which makes up the body of the login and register screens. Everything is in the position i want but i would like to space them out a little. The two input fields, title, subtitle, button and textbutton are too close together vertically.
I tried to use mainaxisalignment.spacebetween but i get a constraint error and everything i have on the screen disappears afterwards except the background.
The body used by the register and login screen:
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.transparent,
body: Container(
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topLeft,
end: Alignment.bottomLeft,
colors: [Color(0xFF1F1F1F), Color(0xFF1F1F1F)],
),
image: DecorationImage(
image: AssetImage("lib/assets/images/register.png"),
alignment: Alignment.topCenter,
),
),
child: Stack(
children: [
Container(
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage('lib/assets/images/bottomleft.png'),
alignment: Alignment.bottomLeft,
),
),
),
Container(
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage('lib/assets/images/toptop.png'),
alignment: Alignment.topRight,
),
),
),
Container(
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage('lib/assets/images/topbig.png'),
alignment: Alignment.topCenter,
repeat: ImageRepeat.repeat),
),
),
Container(
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage('lib/assets/images/top.png'),
alignment: Alignment.topCenter,
repeat: ImageRepeat.repeatX),
),
),
Padding(
padding:
const EdgeInsets.symmetric(horizontal: 25, vertical: 250),
child: ListView(
children: [
if (onBackPressed == null) verticalSpaceLarge,
if (onBackPressed != null) verticalSpaceRegular,
if (onBackPressed != null)
IconButton(
padding: EdgeInsets.zero,
onPressed: onBackPressed,
alignment: Alignment.centerLeft,
icon: Icon(
Icons.arrow_back_ios,
color: Colors.black,
),
),
Center(
child: Text(
title!,
style: TextStyle(
color: Colors.white,
fontSize: 30.0,
fontWeight: FontWeight.bold,
fontFamily: 'Montserrat',
),
),
),
Align(
alignment: Alignment.center,
child: SizedBox(
child: Center(
child: Text(
subtitle!,
style: ktsMediumGreyBodyText,
),
),
),
),
form!,
if (onForgotPassword != null)
Align(
alignment: Alignment.centerRight,
child: GestureDetector(
onTap: onForgotPassword,
child: Center(
child: Text(
'Forgot Password?',
style: ktsMediumGreyBodyText.copyWith(),
),
),
),
),
if (validationMessage != null)
Center(
child: Text(
validationMessage!,
style: TextStyle(
color: Colors.red, fontSize: kBodyTextSize),
),
),
if (validationMessage != null) verticalSpaceRegular,
GestureDetector(
onTap: onMainButtonTapped,
child: Container(
width: double.infinity,
height: 50,
alignment: Alignment.center,
decoration: BoxDecoration(
color: kcPrimaryColor,
borderRadius: BorderRadius.circular(8),
),
child: busy!
? CircularProgressIndicator(
valueColor: AlwaysStoppedAnimation(Colors.white),
)
: Text(
mainButtonTitle!,
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold,
fontSize: 14),
),
),
),
if (onCreateAccountTapped != null)
GestureDetector(
onTap: onCreateAccountTapped,
child: Center(
child: Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
"Don\'t have an account?",
style: TextStyle(color: Colors.white),
),
Text(
"SIGN UP",
style: TextStyle(color: kcPrimaryColor),
),
],
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
"OR SIGN IN WITH",
style: TextStyle(color: kcMediumGreyColor),
),
],
),
],
),
),
),
if (showTermsText!)
Center(
child: Text(
"By signing up you agree to our terms, conditions and privacy policy",
style: ktsMediumGreyBodyText,
textAlign: TextAlign.center,
),
),
],
),
),
],
),
),
);
}
}
the login screen:
Widget build(BuildContext context) {
return ViewModelBuilder<LoginScreenModel>.reactive(
builder: (context, model, child) => Scaffold(
body: AuthenticationLayout(
busy: model.isBusy,
onCreateAccountTapped: () {},
//validationMessage: model.validationMessage,
title: 'SIGN IN',
subtitle: 'please fill the form below',
mainButtonTitle: 'SIGN IN',
form: Column(
children: [
TextField(
decoration: InputDecoration(
hintText: 'Username',
hintStyle: TextStyle(color: Colors.white),
prefixIcon: const Icon(
Icons.person,
color: Colors.white,
),
),
),
TextField(
decoration: InputDecoration(
hintText: 'Password',
hintStyle: TextStyle(color: Colors.white),
prefixIcon: const Icon(
Icons.lock,
color: Colors.white,
),
),
),
],
),
onForgotPassword: () {},
),
),
viewModelBuilder: () => LoginScreenModel(),
);
}
}
Column(
children: <Widget>[
FirstWidget(),
SizedBox(height: 100),
SecondWidget(),
],
),
You should Add SizedBox() in between two Widgets, or Set Padding to your widgets or you use Container also like below:
Using SizedBox()
Column(
children:[
Widget 1(),
SizedBox(height:10),
Widget 2(),
SizedBox(height:10),
Widget 3(),
],
),
Using Padding()
Column(
children:[
Padding(
padding:EdgeInsets.all(8.0)
child: Widget 1(),
),
Padding(
padding:EdgeInsets.all(8.0)
child: Widget 2(),
),
Padding(
padding:EdgeInsets.all(8.0)
child: Widget 3(),
),
],
),
Using Container()
Column(
children:[
Container(
padding:EdgeInsets.all(8.0)
child: Widget 1(),
),
Container(
padding:EdgeInsets.all(8.0)
child: Widget 2(),
),
Container(
padding:EdgeInsets.all(8.0)
child: Widget 3(),
),
],
),
You should use padding on your choice like:
EdgeInsets.all(8.0),
EdgeInsets.only(left:8.0,top:8.0,right:8.0,bottom:8.0),
EdgeInsets.symmetric(vertical: 8.0,horizontal:8.0),
You may add some SizedBox() between or set margin to the components.
Use SizedBox widget to add vertical spacing to your widget.
For e.g
SizedBox(height: 16),
I have a piece of code here which makes up the body of the login and register screens. I added an image at the very top but my question is how do i add multiple images for the body?
I have some images i want to add in different positions for blur effects but whenever do either nothing shows up or gives me an error about the constraints.
When i add multiple containers with a single image in each one, i get the constraint error.
Everything was added in pubspec.yaml and in the folders correctly.
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.transparent,
body: Container(
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topLeft,
end: Alignment.bottomLeft,
colors: [Color(0xFF1F1F1F), Color(0xFF1F1F1F)],
),
image: DecorationImage(
image: AssetImage("lib/assets/images/register.png"),
alignment: Alignment.topCenter,
//fit: BoxFit.cover,
),
),
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 25, vertical: 250),
child: ListView(
children: [
if (onBackPressed == null) verticalSpaceLarge,
if (onBackPressed != null) verticalSpaceRegular,
if (onBackPressed != null)
IconButton(
padding: EdgeInsets.zero,
onPressed: onBackPressed,
alignment: Alignment.centerLeft,
icon: Icon(
Icons.arrow_back_ios,
color: Colors.black,
),
),
Center(
child: Text(
title!,
style: TextStyle(
color: Colors.white,
fontSize: 30.0,
fontWeight: FontWeight.bold,
fontFamily: 'Montserrat',
),
),
),
verticalSpaceSmall,
SizedBox(
child: Center(
child: Text(
subtitle!,
style: ktsMediumGreyBodyText,
),
),
),
verticalSpaceRegular,
form!,
if (onForgotPassword != null)
Align(
alignment: Alignment.centerRight,
child: GestureDetector(
onTap: onForgotPassword,
child: Center(
child: Text(
'Forgot Password?',
style: ktsMediumGreyBodyText.copyWith(),
),
),
),
),
verticalSpaceRegular,
if (validationMessage != null)
Center(
child: Text(
validationMessage!,
style:
TextStyle(color: Colors.red, fontSize: kBodyTextSize),
),
),
if (validationMessage != null) verticalSpaceRegular,
GestureDetector(
onTap: onMainButtonTapped,
child: Container(
width: double.infinity,
height: 50,
alignment: Alignment.center,
decoration: BoxDecoration(
color: kcPrimaryColor,
borderRadius: BorderRadius.circular(8),
),
child: busy!
? CircularProgressIndicator(
valueColor: AlwaysStoppedAnimation(Colors.white),
)
: Text(
mainButtonTitle!,
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold,
fontSize: 14),
),
),
),
verticalSpaceRegular,
if (onCreateAccountTapped != null)
GestureDetector(
onTap: onCreateAccountTapped,
child: Center(
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
verticalSpaceMedium,
Text(
"Don\'t have an account?",
style: TextStyle(color: Colors.white),
),
horizontalSpaceTiny,
Text(
"SIGN UP",
style: TextStyle(color: kcPrimaryColor),
),
],
),
),
),
if (showTermsText!)
Center(
child: Text(
"By signing up you agree to our terms, conditions and privacy policy",
style: ktsMediumGreyBodyText,
textAlign: TextAlign.center,
),
),
],
),
),
),
);
}
}