How to fix icons in AppBar when changing toolbarHeight in Flutter? - android

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,
),
),
),
],
),
),

Related

How do i make the last widget always be at the bottom of the screen?

So i'm currently creating a detail page. Im trying to get a particular look and ive tried quite a few different approach such as using expanded Slivefill but im unable to get the desired look.
From the above image, From the left the first case is acceptable as there is a larger amount of text, the second image is where i have a problem. im trying to get it the very least fill to bottom of the screen.
the last image is the ideal condition i would like to achieve if there is a smaller amount of data.
if anybody could assist or point me to the right direction it would be highly appreciated
Scaffold(
body: CustomScrollView(
slivers: [
SliverAppBar(
bottom: PreferredSize(
preferredSize: const Size(0, 1),
child: Container(),
),
pinned: false,
expandedHeight: MediaQuery.of(context).size.height * 0.4,
centerTitle: true,
flexibleSpace: Stack(
children: [
Positioned(
child: FlexibleSpaceBar(
background: Image.network(
loadedEvent.imageUrl,
fit: BoxFit.cover,
),
),
),
Positioned(
bottom: -1,
left: 0,
right: 0,
child: Container(
height: 20,
decoration: const BoxDecoration(
color: Color(0xfffffcf2),
borderRadius: BorderRadius.vertical(
top: Radius.circular(20),
),
),
),
),
],
),
),
SliverToBoxAdapter(
child: SingleChildScrollView(
child: Container(
color: Color(0xfffffcf2),
child: ListView(
physics: const NeverScrollableScrollPhysics(),
shrinkWrap: true,
padding: const EdgeInsets.all(20.0),
children: [
Text(
loadedEvent.title,
textAlign: TextAlign.center,
style: const TextStyle(
fontSize: 40,
fontWeight: FontWeight.bold,
letterSpacing: 1.0,
),
),
Spacer(),
Flexible(
fit: FlexFit.tight,
flex: 8,
child: RichText(
text: TextSpan(
style: const TextStyle(
color: Colors.black,
fontSize: 18.0,
),
text: loadedEvent.description,
),
),
),
Spacer(),
Flexible(
fit: FlexFit.loose,
child: Container(
color: Colors.black,
child: Text(loadedEvent.date),
),
),
],
),
),
),
),
],
),
);
Is this what you want to achieve?
#override
Widget build(BuildContext context) {
return Scaffold(
body: Stack(
children: [
CustomScrollView(
slivers: [
SliverAppBar(
bottom: PreferredSize(
preferredSize: const Size(0, 1),
child: Container(),
),
pinned: false,
expandedHeight: MediaQuery.of(context).size.height * 0.4,
centerTitle: true,
flexibleSpace: Stack(
children: [
Positioned(
child: FlexibleSpaceBar(
background: Image.network(
loadedEvent.imageUrl,
fit: BoxFit.cover,
),
),
),
Positioned(
bottom: -1,
left: 0,
right: 0,
child: Container(
height: 20,
decoration: const BoxDecoration(
color: Color(0xfffffcf2),
borderRadius: BorderRadius.vertical(
top: Radius.circular(20),
),
),
),
),
],
),
),
SliverToBoxAdapter(
child: Container(
color: const Color(0xfffffcf2),
height: MediaQuery.of(context).size.height,
padding: const EdgeInsets.all(20.0),
child: Column(
children: [
Text(
loadedEvent.title,
textAlign: TextAlign.center,
style: const TextStyle(
fontSize: 40,
fontWeight: FontWeight.bold,
letterSpacing: 1.0,
),
),
const Spacer(),
Flexible(
fit: FlexFit.tight,
flex: 8,
child: RichText(
text: TextSpan(
style: const TextStyle(
color: Colors.black,
fontSize: 18.0,
),
text: loadedEvent.description,
),
),
),
const Spacer(),
],
),
),
),
],
),
Positioned(
bottom: 0.0,
child: Container(
color: Colors.black,
padding: const EdgeInsets.all(8.0),
width: MediaQuery.of(context).size.width,
child: Text(
loadedEvent.date,
style: const TextStyle(
color: Colors.white,
),
textAlign: TextAlign.center,
),
),
),
],
),
);
}
You can use flexible widget to the previous widget to set last widget to end of the screen. But you can't use scrollview otherwise ypu will get an error.

How to remove padding from top of ListTile in Drawer?

I can not remove the indent from the first ListTile in any way. I think this is some kind of default indent, but I could not overcome it. Is it possible? Attached is the code and screenshot.
Drawer(
child: Container(
padding: EdgeInsets.zero,
child: Column(
children: <Widget>[
SizedBox(
height: 88.0,
width: 1000,
child: DrawerHeader(
decoration: BoxDecoration(
color: Colors.blue,
),
child: Text(
'Настройки',
style: TextStyle(
color: Colors.white,
fontSize: MainStyle.p.fontSize
),
),
),
),
Expanded(
child: Column(
children: <Widget>[
ListTile(
title: Text(
'Язык',
style: TextStyle(
fontSize: MainStyle.p.fontSize
),
),
subtitle: Text(
"Русский",
),
trailing: IconButton(
icon: Icon(Icons.edit),
color: Colors.black,
onPressed: () {
},
),
),
ListTile(
title: Text(
'Выход',
style: TextStyle(
fontSize: MainStyle.p.fontSize
),
),
onTap: () {
exit();
},
),
],
)
),
Container(
child: Align(
alignment: FractionalOffset.bottomCenter,
child: Column(
children: <Widget>[
ListTile(
title: Text(
globalState.version,
style: TextStyle(
fontSize: 15,
color: Colors.grey
),
textAlign: TextAlign.center,
),
),
],
)
)
),
],
),
)
);
P.S. There is not any details, but StackOverflow make me write more text, because of "It looks like your post is mostly code; please add some more details."
add this line to your DrawerHeader:
margin: EdgeInsets.zero,

Visibility of Welcome Back Container and Bottom Navigation Bar on screen all time while scrolling

I am writing a code in flutter for my application and my page looks like this:
Screen View from Starting
Screen View from Ending
What I want is that my Widget where I have written welcome back etc and an avatar shown with it should remain all-time visible even when I am scrolling. Also, i want my Bottom Navigation bar to remain visible as well.
My code for Welcome Screen:
Widget build(BuildContext context) {
Size size = MediaQuery.of(context).size;
return Scaffold(
appBar: AppBar(
backgroundColor: const Color(0xffe8e5af),
elevation: 0,
leading: IconButton(
icon: Icon(
Icons.menu,
color: Colors.black,
),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) {
return BluetoothConnectBand();
},
),
);
},
),
),
body: SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Stack(
children: [
Container(
padding: EdgeInsets.symmetric(vertical: 22, horizontal: 47),
width: size.width,
height: 157.0,
decoration: BoxDecoration(
borderRadius: BorderRadius.only(
bottomRight: Radius.circular(40.0),
bottomLeft: Radius.circular(40.0),
),
color: const Color(0xffe8e5af),
),
child: Column(
//mainAxisAlignment: MainAxisAlignment.spaceEvenly,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Welcome Back\nNabia',
style: TextStyle(
fontFamily: 'Montserrat',
fontWeight: FontWeight.w800,
fontSize: 21,
color: const Color(0xff000000),
height: 1.380952380952381,
),
textHeightBehavior:
TextHeightBehavior(applyHeightToFirstAscent: false),
textAlign: TextAlign.left,
),
SizedBox(
height: 23.0,
),
Text(
'Check your daily history',
style: TextStyle(
fontFamily: 'Montserrat',
fontSize: 13,
color: const Color(0xff6c6c6c),
height: 1.5384615384615385,
fontWeight: FontWeight.w600),
textHeightBehavior:
TextHeightBehavior(applyHeightToFirstAscent: false),
textAlign: TextAlign.left,
),
],
),
),
Container(
alignment: Alignment.centerRight,
width: size.width,
padding: EdgeInsets.symmetric(horizontal: 33),
child: CircleAvatar(
radius: 48,
backgroundColor: Colors.white,
child: CircleAvatar(
backgroundImage: AssetImage('assets/images/avatar.jpg'),
radius: 42,
),
),
),
],
),
and for Bottom Navigation Bar is:
Container(
height: 70,
decoration: BoxDecoration(
borderRadius: BorderRadius.only(
topRight: Radius.circular(20), topLeft: Radius.circular(20)),
boxShadow: [
BoxShadow(color: Colors.grey, spreadRadius: 0, blurRadius: 5),
],
),
child: ClipRRect(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(20.0),
topRight: Radius.circular(20.0),
),
child: BottomNavigationBar(
//elevation: 7,
type: BottomNavigationBarType.fixed,
//fixedColor: const Color(0xff898a8f),
backgroundColor: Colors.white,
unselectedFontSize: 10,
selectedFontSize: 10,
selectedLabelStyle: optionStyle,
currentIndex: _currentIndex,
selectedItemColor: const Color(0xffd4d411),
unselectedItemColor: const Color(0xffd4d411),
onTap: onTabTapped, // this will be set when a new tab is tapped
items: [
BottomNavigationBarItem(
icon: new Icon(Icons.home),
title: new Text(
'Home',
style: TextStyle(
fontFamily: 'Montserrat',
fontSize: 10,
color: Colors.black,
),
),
),
BottomNavigationBarItem(
icon: new Icon(Icons.mail),
title: new Text(
'Caregiver',
style: TextStyle(
fontFamily: 'Montserrat',
fontSize: 10,
color: Colors.black,
),
),
),
BottomNavigationBarItem(
icon: Icon(Icons.person_pin_circle),
title: Text(
'History',
style: TextStyle(
fontFamily: 'Montserrat',
fontSize: 10,
color: Colors.black,
),
),
),
BottomNavigationBarItem(
icon: Icon(Icons.person),
title: Text(
'Profile',
style: TextStyle(
fontFamily: 'Montserrat',
fontSize: 10,
color: Colors.black,
),
),
),
],
),
),
),
Please help me out with what I should write to make my screen work perfectly because I am a beginner to Flutter and I am still learning.
You could try to use an Expanded widget to let the scrollable area take up the remaining space. You would have to move the welcome-widget outside of the SingleChildScrollView.
Here's a simplified example that might help you.
return Scaffold(
appBar: AppBar(),
body: Column(
children: [
_Welcome(),
Expanded(
child: SingleChildScrollView(
child: _Charts(),
),
),
],
),
bottomNavigationBar: BottomNavigationBar(
items: [
BottomNavigationBarItem(
icon: Icon(Icons.ac_unit),
label: "1",
),
BottomNavigationBarItem(
icon: Icon(Icons.ac_unit),
label: "2",
),
],
),
);
When the BottomNavigationBar is passed into the Scaffold's bottomNavigationBar parameter, it should always be visible and remain on the bottom of the screen.

Why TabBar View hides under Tab Bar?

imageWhen I scroll my screen flexible space collapses which is fine but as I scroll my tab bar view a part of It moves under tab bar even if I don't add scroll in Tab Bar view. I am new to flutter, this is my first project. Please help me with this issue. Also I am new to stack overflow. BTW I have to add these lines because stack overflow is giving me this error "It looks like your post is mostly code; please add some more details." :) :)
Heading ##return Scaffold(
appBar: AppBar(title: Text("Author"),),
body: NestedScrollView(
controller: _scrollController,
headerSliverBuilder: (BuildContext context, bool boxIsScrolled){
return <Widget>[
SliverAppBar(
leading: Container(),
backgroundColor: Colors.white,
pinned: true,
floating: true,
forceElevated: boxIsScrolled,
bottom: TabBar(
controller: _tabController,
indicatorSize: TabBarIndicatorSize.tab,
tabs: [
Tab(child: Row(mainAxisAlignment:MainAxisAlignment.center,children:[Icon(Icons.photo_sharp, color: Colors.black,),SizedBox(width: 10.0,),Text("Posts", style: TextStyle(color: Colors.black),)],),),
Tab(child: Row(mainAxisAlignment:MainAxisAlignment.center,children:[Icon(Icons.dashboard_rounded, color: Colors.black,),SizedBox(width: 10.0,),Text("Courses", style: TextStyle(color: Colors.black),)],),),
],
),
flexibleSpace: SafeArea(
child: FlexibleSpaceBar(
collapseMode: CollapseMode.pin,
background: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
margin: EdgeInsets.all(8),
child: Row(
children: [
CircleAvatar(
radius: 45.0,
child: author.photo_url == null ? Image.asset("assets/user.png") : imageUrl == null ? CircularProgressIndicator():
ClipRRect(
borderRadius: BorderRadius.circular(83.0),
child: Image(
image: NetworkImage(imageUrl),
width: 140,
height: 140,
fit: BoxFit.fill,
),
)),
Expanded(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Text("Followers", style: TextStyle(fontWeight: FontWeight.w700, fontSize: 19.0)),
SizedBox(height: 12.0,),
Text("0", style: TextStyle(fontWeight: FontWeight.w500, fontSize: 18.0)),
],
),
Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Text("Posts", style: TextStyle(fontWeight: FontWeight.w700, fontSize: 19.0)),
SizedBox(height: 12.0,),
Text("0", style: TextStyle(fontWeight: FontWeight.w500, fontSize: 18.0)),
],
),
Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Text("Courses", style: TextStyle(fontWeight: FontWeight.w700, fontSize: 19.0)),
SizedBox(height: 12.0,),
Text("0", style: TextStyle(fontWeight: FontWeight.w500, fontSize: 18.0)),
],
)
],
),
)
],
),
),
Padding(
padding: EdgeInsets.fromLTRB(18, 8, 0, 0),
child: Text("${author.name}", style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold, letterSpacing: 1.0),),
),
Padding(
padding: EdgeInsets.fromLTRB(20, 5, 0, 0),
child: Text("${author.qualification}", style: TextStyle(letterSpacing: 1.0),),
),
Padding(
padding: EdgeInsets.fromLTRB(20, 5, 0, 0),
child: Text("${author.profession}", style: TextStyle(letterSpacing: 1.0),),
),
Padding(
padding: EdgeInsets.fromLTRB(20, 15, 20, 0),
child: Container(
width: deviceWidth,
child: RaisedButton.icon(
color: Colors.blue,
label: Text(followedAuthorsID.contains(author.id) ? "Following" : "Follow", style: TextStyle(color: Colors.white, fontWeight: FontWeight.w700, letterSpacing: 0.5),),
icon: Icon(followedAuthorsID.contains(author.id) ? Icons.check_box : Icons.person_add, color: Colors.white,),
onPressed: (){
followAuthor(author, followedAuthorsID.contains(author.id));
},
),
),
),
Divider(height: 40,color: Colors.black,),
]),
),
),
expandedHeight: 305,
)
];
},
body: TabBarView(
controller: _tabController,
children: [
GridView.count(
childAspectRatio: 1,
shrinkWrap: true,
physics: ScrollPhysics(),
crossAxisCount: 3,
children: [
Container(color: Colors.red,),
Container(color: Colors.green,),
Container(color: Colors.red,),
Container(color: Colors.green,),
],
),
// ListView(
// children : [
// SizedBox(height: 100),
// Center(child: Text("No Posts Added", style: TextStyle(fontWeight: FontWeight.w500, fontSize: 22, letterSpacing: 0.5),)),
ListView(
children : [
SizedBox(height: 100,),
Center(child: Text("No Courses Added", style: TextStyle(fontWeight: FontWeight.w500, fontSize: 22, letterSpacing: 0.5),)),
SizedBox(height: 25),
CircleAvatar(
radius: 45,
child: Icon(Icons.dashboard_rounded, size: 35,),
),
]
),
],
),
),
);

Position widget anywhere without pushing other widgets

I've followed a Flutter youtube tutorial and ended up with a layout like this:
How can I move CircleAvatar widget far right and bring other widgets up? So it looks like this (I photoshoped this):
This is what some of my code looks like:
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.grey[900],
appBar: AppBar(
title: Text("User information"),
centerTitle: true,
backgroundColor: Colors.grey[850],
elevation: 0.0,
),
floatingActionButton: FloatingActionButton(
onPressed: () {
setState( () {
userLevel++;
});
},
backgroundColor: Colors.red[400],
child: Icon(Icons.add),
),
body: Padding(
padding: EdgeInsets.fromLTRB(30.0, 35.0, 30.0, 0.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Center(
child: CircleAvatar(
backgroundImage: AssetImage("assets/vayneAvatar.jpg"),
radius: 40.0,
),
),
Divider(height: 60.0, color: Colors.grey[700]),
Text(
"USERNAME",
style: TextStyle(
color: Colors.grey,
letterSpacing: 2.0,
),
),
SizedBox(height: 8.0),
Text(
"user1",
style: TextStyle(
color: Colors.red[400],
fontWeight: FontWeight.bold,
fontSize: 22.0,
letterSpacing: 2.0,
),
),
Thanks!
You need to use Stack widget which takes list of children, where you can easily position your widgets by Positioned widget.

Categories

Resources