Custom widget of app bar with a humburger menu as ElevatedButton with a Drawer doesn't work OnPressed - flutter

I am facing a problem with my custom app bar. I would like it to have a drawer but it doesn't work. I just don't know how to make it being able to open.
It is a custom app bar widget named Pasek (which stands for top bar in my language).
It has a logo picture which on click moves you to the first page of the app.
Next to it there is humburger menu with a drawer but I do not know why it doesn't work. I click on it and nothing happens.
Any ideas?
class Pasek extends StatelessWidget with PreferredSizeWidget {
#override
Size get preferredSize => Size.fromHeight(50.0);
const Pasek({
Key? key,
}) : super(key: key);
#override
Widget build(BuildContext context) {
return AppBar(
actions: <Widget>[
Padding(
padding: EdgeInsets.only(right: 35.0),
child: ElevatedButton(
child: Icon(Icons.menu, color: Colors.white),
onPressed: () {
Scaffold(
endDrawer: Drawer(
child: ListView(
padding: EdgeInsets.zero,
children: const <Widget>[
DrawerHeader(
decoration: BoxDecoration(
color: Colors.black,
),
child: Text(
'Menu',
style: TextStyle(
color: Colors.pink,
fontSize: 24,
),
),
),
ListTile(
leading: Icon(Icons.message),
title: Text('Messages'),
),
ListTile(
leading: Icon(Icons.account_circle),
title: Text('Profile'),
),
ListTile(
leading: Icon(Icons.settings),
title: Text('Settings'),
),
],
),
),
);
},
)),
],
backgroundColor: Colors.black,
title: GestureDetector(
onTap: () {
Navigator.of(context).push(
MaterialPageRoute(
builder: (_) => FirstPage(),
),
);
}, // Image tapped
child: Image.asset(
'images/logo.png',
fit: BoxFit.scaleDown,
height: 30,
width: 200,
),
));
}
}

Related

How can i implement navigation drawer under appbar in flutter

I want to implement navigation drawer in flutter like this screenshot. But don't know how.
Please give me some code hint.
Thank you.
This is the image I like to archive
use the Drawer Widget in scaffold
this is an example from the official documentation
Scaffold(
appBar: AppBar(
title: const Text('Drawer Demo'),
),
drawer: Drawer(
child: ListView(
padding: EdgeInsets.zero,
children: const <Widget>[
DrawerHeader(
decoration: BoxDecoration(
color: Colors.blue,
),
child: Text(
'Drawer Header',
style: TextStyle(
color: Colors.white,
fontSize: 24,
),
),
),
ListTile(
leading: Icon(Icons.message),
title: Text('Messages'),
),
ListTile(
leading: Icon(Icons.account_circle),
title: Text('Profile'),
),
ListTile(
leading: Icon(Icons.settings),
title: Text('Settings'),
),
],
),
),
);
this is the result =>
You have to use the Drawer widget.
Scaffold(
drawer: Drawer(
child: ListView(
padding: EdgeInsets.zero,
children: [
ListTile(
title: const Text('Item 1'),
onTap: (){
// do something
},
),
ListTile(
title: const Text('Item 2'),
onTap: (){
// do something
},
),
],
),
),
...
And that's pretty much it! Learn more about Drawer, here.
An easy to archive this is using another Scaffold on body and using drawer there. And to control the drawer use ScaffoldState GlobalKey.
Result
Widget
class _MyApp extends StatefulWidget {
#override
State<_MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<_MyApp> {
static final GlobalKey<ScaffoldState> _key = GlobalKey();
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
leading: IconButton(
onPressed: () {
if (_key.currentState != null) {
if (_key.currentState!.isDrawerOpen) {
Navigator.pop(_key.currentContext!);
} else {
_key.currentState!.openDrawer();
}
}
},
icon: const Icon(
Icons.more,
),
),
),
body: Scaffold(
key: _key,
drawer: Drawer(
child: Container(
color: Colors.red,
),
),
body: Column(
children: const [
Text("Child"),
],
),
));
}
}

Scrollable Listview in sidebar flutter

I am using Default Sidebar but getting error while scroll
'The $controllerForError is currently attached to more than one '
'ScrollPosition.',
here is Sidebar Widget
#override
Widget build(BuildContext context) {
return ListView(
children: <Widget>[
DrawerHeader(
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage("assets/images/bgimage.jpg"),
fit: BoxFit.cover),
color: Colors.blue,
),
child: Center(
child: Column(
children: [
Text(
'${store.user['name']}',
style: TextStyle(color: Colors.white, fontSize: 25),
),
Lottie.asset(
'assets/lottie/coin.json',
width: 50,
height: 50,
),
Text(
'${store.user['wallet']}',
style: TextStyle(color: Colors.white, fontSize: 20),
),
],
)),
),
ListTile(
leading: Icon(Icons.home),
title: Text('Home'),
onTap: () {
Navigator.popAndPushNamed(context, '/home');
},
),
ListTile(
leading: Icon(Icons.assessment_outlined),
title: Text('Loss/Profit'),
onTap: () {
Navigator.pop(context);
},
),
ListTile(
leading: Icon(Icons.calendar_today),
title: Text('Results'),
onTap: () {
Navigator.popAndPushNamed(context, '/result');
},
),
ListTile(
leading: Icon(Icons.supervised_user_circle),
title: Text('Referrals'),
onTap: () {
Navigator.pop(context);
},
),
],
);
}
}
Using in homepage
drawer: Drawer(
child: Sidebar(),
),
where is scroll position is using multiple
by default drawer is already scrollable. i think the cause of not being able to scroll is not in the drawer

How to change positions of icons in AppBar in flutter?

I am trying to reposition my "compass" icon near the "search" icon from the App bar. Everytime i try to make a change in the container with higher value 55 for example "padding: const EdgeInsets.symmetric(horizontal: 50)," i get error stack over flow. Also when i try to change the logo(png) the allingment, nothing happens. Help please!
Image
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
flexibleSpace: Container(
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topLeft,
end: Alignment.bottomRight,
colors: <Color>[Colors.pink[400], Colors.blue[400]]
),
),
),
title: Row(
children: [
Container(
alignment: Alignment.center,
height: 40,
child: SizedBox(
child: Image.asset(
'assets/images/logox.png',
)
),
),
Container(
padding: const EdgeInsets.symmetric(horizontal: 50),
child: SizedBox(
child: Icon(
Icons.explore_rounded,
))),
// Container(child: Icon(Icons.explore_rounded)),
],
),
actions: [
GestureDetector(
onTap: () {
// authMethods.signOut();
Navigator.pushReplacement(
context,
MaterialPageRoute(
builder: (context) => SearchScreen(),
));
},
child: Container(
padding: EdgeInsets.symmetric(horizontal: 16),
child: Icon(Icons.search)),
)
],
),
drawer: MainDrawer(),
//body: Body(),
bottomNavigationBar: GradientBottomNavigationBar(
fixedColor: Colors.white,
backgroundColorStart: Colors.pink[400],
backgroundColorEnd: Colors.blue[400],
items: <BottomNavigationBarItem>[
BottomNavigationBarItem(
icon: Icon(Icons.home), title: Text('Home')),
BottomNavigationBarItem(
icon: Icon(Icons.wallet_membership), title: Text('QUA')),
BottomNavigationBarItem(
icon: Icon(Icons.help), title: Text('Help')),
],
currentIndex: _selectedIndex,
onTap: _onItemTapped,
),
floatingActionButton: FloatingActionButton(
backgroundColor: Colors.pink,
elevation: 50,
hoverColor: Colors.red,
autofocus: true,
onPressed: () {
print('hi');
},
child: Icon(
Icons.comment,
),
tooltip: 'Pick Image',
),
floatingActionButtonLocation: FloatingActionButtonLocation.endFloat);
}
void _onItemTapped(int index) {
setState(() {
_selectedIndex = index;
});
}
}
There is actions property in AppBar widget which is mainly used to put icons in AppBar. And in your case centerTitle is used to align your image to center
Output
Full code
class MyHomePage extends StatefulWidget {
final Function onItemPressed;
MyHomePage({
Key key,
this.onItemPressed,
}) : super(key: key);
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
flexibleSpace: Container(
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topLeft,
end: Alignment.bottomRight,
colors: <Color>[Colors.pink[400], Colors.blue[400]]),
),
),
centerTitle: true,
title: Container(
alignment: Alignment.center,
height: 40,
child: SizedBox(
child: Image.asset(
'assets/logo.png',
)),
),
actions: [
IconButton(
onPressed: () {},
icon: Icon(Icons.explore_rounded),
),
IconButton(
onPressed: () {},
icon: Icon(Icons.search),
)
],
),
);
}
}
Material appbar has an actions property, you can use that to put search and compass icon together. In order to achieve the same remove
Container(
padding: const EdgeInsets.symmetric(horizontal: 50),
child: SizedBox(
child: Icon(
Icons.explore_rounded,
))),
from its current position and add it into the actions property just above the search button.

How can I create a line under the SliverAppBar in flutter?

I would like to add a line under the appbar as in image two.
How can I make this line in flutter?
The image one is the app now and the image two is the line under the sliverAppBar
*already tried to use a container and a divider
class HomeScreen extends StatefulWidget {
#override
_HomeScreenState createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
#override
Widget build(BuildContext context) {
return Scaffold(
body: CustomScrollView(
slivers: <Widget>[
SliverAppBar(
backgroundColor: Colors.white,
elevation: 0,
leading: IconButton(
icon: SvgPicture.asset(
'assets/icons/home_icon.svg',
color: Colors.black,
),
onPressed: () {}
),
actions: [
IconButton(
icon: SvgPicture.asset(
'assets/icons/search_icon.svg',
color: Colors.black,
),
onPressed: () {
}
),
IconButton(
icon: SvgPicture.asset(
'assets/icons/shopping_bag_icon.svg',
color: Colors.black,
),
onPressed: () {},
),
IconButton(
icon: SvgPicture.asset(
'assets/icons/profile_icon.svg',
color: Colors.black,
),
onPressed: () {}
),
],
floating: true,
),
SliverList(
delegate: SliverChildBuilderDelegate(
(context, index) => ListTile(title: Text('Item #$index')),
childCount: 1000,
),
),
],
),
);
}
}
more txt for the stack valid my questions
There is a 'bottom' attribute in the SliverAppBar Widget which takes a preferred size Widget, you can give it the following:
bottom: PreferredSize(
preferredSize: Size(double.infinity, 5),
child: Divider(color: Colors.black),
),
A contribution to omar hatem answer, the property "size" should be "preferredSize"
bottom: PreferredSize(
preferredSize: Size(double.infinity, 5),
child: Divider(color: Colors.black),
),
In my case, I needed more control over my line under the app bar sliver so I ended up implementing like so:
SliverPersistentHeader(
pinned: true,
delegate: MySliverElevationDelegate(
child: Material(
//elevation: 4.0,
child: Container(
color: Colors.black,
),
),
),
)
Cheers!

Selecting a specific BottomNavigationBar when routing from another widget (Flutter)

Please, help. This is my first project using Flutter. I am making an app for pets.
I have Homepage widget that has 4 bottom Navbar (Home, Photos, Medical, Profile). In Profile I have a button "About", which opens a widget about us.
But when I am trying to return to back from About, it returns to "Home" NavBottombar. I am trying to select Profile NavBottomBar.
I think that is related to current index in Homepage, which equals 0 at the beginning. But how can I change from 0 to 2 while routing?
homepage.dart
import 'package:flutter/material.dart';
import 'placeholder_widget.dart';
import 'dashboard.dart';
import 'medical.dart';
import 'profile.dart';
import 'about.dart';
void main() => runApp(MaterialApp(
home: Homepage(),
));
class Homepage extends StatefulWidget {
#override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<Homepage> {
int _currentIndex = 0;
final List<Widget> _children = [
Dashboard(),
PlaceholderWidget(Colors.deepOrange),
PlaceholderWidget(Colors.red),
// Medical(),
Profile()
];
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('Furball Tales'),
backgroundColor: Colors.cyanAccent[400],
),
body: _children[_currentIndex],
bottomNavigationBar: BottomNavigationBar(
onTap: onTabTapped,
currentIndex: _currentIndex,
items: const <BottomNavigationBarItem>[
BottomNavigationBarItem(
icon: Icon(Icons.home),
title: Text('Home'),
),
BottomNavigationBarItem(
icon: Icon(Icons.perm_media),
title: Text('Photos'),
),
BottomNavigationBarItem(
icon: Icon(Icons.local_hospital),
title: Text('Medical'),
),
BottomNavigationBarItem(
icon: Icon(Icons.perm_identity),
title: Text('Profile'),
),
],
selectedItemColor: Colors.cyanAccent[400],
unselectedItemColor: Colors.grey[600],
),
),
);
}
void onTabTapped(int index) {
setState(() {
_currentIndex = index;
});
}
}
about.dart
import 'package:flutter/material.dart';
import 'profile.dart';
import 'homepage.dart';
class About extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('About FurBallTales'),
backgroundColor: Colors.cyanAccent[400],
leading: GestureDetector(
onTap: () {
Navigator.of(context).pushAndRemoveUntil(
MaterialPageRoute(builder: (context) {
return Homepage();
}), ModalRoute.withName('/'));
},
child: Icon(
Icons.arrow_back,
)),
),
body: ListView(
padding: const EdgeInsets.all(2),
children: <Widget>[
Container(
decoration:
BoxDecoration(border: Border.all(color: Colors.blueAccent)),
child: Column(
children: <Widget>[
Container(
height: 30,
margin: EdgeInsets.all(5),
child: Text(
'OUR MISSION',
textAlign: TextAlign.center,
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 20,
color: Colors.tealAccent[400]),
),
),
Container(
height: 25,
margin: EdgeInsets.all(5),
child: Text(
'Strengthening the bond of owners and pets, more than ever',
textAlign: TextAlign.center,
style: TextStyle(
fontWeight: FontWeight.bold, color: Colors.black),
),
),
],
),
),
Container(
height: 50,
color: Colors.amber[600],
child: const Center(child: Text('Entry A')),
),
Container(
height: 50,
color: Colors.amber[500],
child: const Center(child: Text('Entry B')),
),
Container(
height: 50,
color: Colors.amber[100],
child: const Center(child: Text('Entry C')),
),
],
),
);
}
}
profile.dart
import 'package:flutter/material.dart';
import 'sign_in.dart';
import 'login_page.dart';
import 'about.dart';
import 'donation.dart';
class Profile extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
CircleAvatar(
radius: 80,
backgroundImage: NetworkImage(
'https://encrypted-tbn0.gstatic.com/images?q=tbn%3AANd9GcSxDoD5caxFUy_dn0w6wl01m882CeJHNVOCRg&usqp=CAU'),
),
Text(
'<$name>',
style: TextStyle(
fontFamily: 'SourceSansPro',
fontSize: 25,
),
),
Text(
'<$email>',
style: TextStyle(
fontSize: 20,
fontFamily: 'SourceSansPro',
color: Colors.red[400],
letterSpacing: 2.5,
),
),
SizedBox(
height: 20.0,
width: 200,
child: Divider(
color: Colors.teal[200],
),
),
// this is about page-----------------------------------------
InkWell(
onTap: () {
Navigator.of(context).pushAndRemoveUntil(
MaterialPageRoute(builder: (context) {
return About();
}), ModalRoute.withName('/about'));
},
child: Card(
color: Colors.white,
margin:
EdgeInsets.symmetric(vertical: 10.0, horizontal: 25.0),
child: ListTile(
leading: Icon(
Icons.help,
color: Colors.teal[900],
),
title: Text(
'About',
style:
TextStyle(fontFamily: 'BalooBhai', fontSize: 20.0),
),
)),
),
InkWell(
onTap: () {
Navigator.of(context).pushAndRemoveUntil(
MaterialPageRoute(builder: (context) {
return Donation();
}), ModalRoute.withName('/about'));
},
child: Card(
color: Colors.white,
margin:
EdgeInsets.symmetric(vertical: 10.0, horizontal: 25.0),
child: ListTile(
leading: Icon(
Icons.monetization_on,
color: Colors.teal[900],
),
title: Text(
'Donation',
style: TextStyle(fontSize: 20.0, fontFamily: 'Neucha'),
),
),
),
),
InkWell(
onTap: () {
signOutGoogle();
Navigator.of(context).pushAndRemoveUntil(
MaterialPageRoute(builder: (context) {
return LoginPage();
}), ModalRoute.withName('/'));
},
child: Card(
color: Colors.white,
margin:
EdgeInsets.symmetric(vertical: 10.0, horizontal: 25.0),
child: ListTile(
leading: Icon(
Icons.account_circle,
color: Colors.teal[900],
),
title: Text(
'LOGOUT',
style: TextStyle(fontSize: 20.0, fontFamily: 'Neucha'),
),
),
),
),
],
),
),
),
);
}
}
Instead of using pushAndRemoveUntil in your About page, you can use Navigator.pop(context)( which removes the view from the Navigator stack):
I added a demo using your code as an example:
class About extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('About FurBallTales'),
backgroundColor: Colors.cyanAccent[400],
leading: GestureDetector(
onTap: () {
Navigator.pop(context); // pop the view
},
child: Icon(
Icons.arrow_back,
)),
),
...
);
}
}
NOTE:
With this approach, the state of the BottomNavigationBar is reserved.
Thank you for everyone, who helped me.
The problem has been solved this way:
First, I pushed to new page.
onTap: () {
Navigator.push(context,
MaterialPageRoute(builder: (context) => About()));
}
Then made pop context.
onTap: () {
Navigator.pop(context);
},
It returned initial position.
Where it says return Homepage(); in about.dart you could change that to return the profile widget.