Change Drawer Icon of Drawer Widget being returned from an external Class - flutter

I'm trying to change the icon and color of my drawer widget in Dart. I've found ways of doing it but none that apply to my scenario. My custom drawer widget is being returned from another class and so I can't change the leading icon in the home class where the app bar is or it will replace my current drawer. I won't show all the code because I don't believe it would be necessary. Any help would be appreciated.
My Current drawer and method of calling it:
Drawer class:
import 'package:flutter/material.dart';
import 'package:new_app/Users.dart';
import '../main.dart';
class MainDrawer extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Drawer(
child: Column(
children: <Widget>[
Container(
width: double.infinity,
padding: EdgeInsets.all(20),
color: Theme.of(context).primaryColor,
child: Center(
child: Column(
children: [
Container(
Menu Class/ home page:
import 'screens/drawer_main.dart';
class Home extends StatefulWidget {
#override
_HomeState createState() => _HomeState();
}
class _HomeState extends State<Home> {
#override
Widget build(BuildContext context) {
return WillPopScope(
onWillPop: () {
return new Future(() => false);
},
child: Scaffold(
backgroundColor: Colors.blueGrey[900],
appBar: AppBar(
//backgroundColor: Colors.blueGrey[900],
backgroundColor: Colors.transparent,
automaticallyImplyLeading: true,
title: Text(
"Home Page",
style: TextStyle(color: Colors.white),
),
actions: <Widget>[
//Profile Pic
IconButton(
icon: Icon(Icons.circle, color: Colors.white),
tooltip: 'Comment Icon',
onPressed: () {},
),
MainPopUp(), //IconButton
],
//IconButton
brightness: Brightness.dark,
),
//Current Method of Calling the Drawer:
drawer: MainDrawer(),
body: Center(

Add the leading property in the App Bar and then call the Drawer Widget Programmatically.
Scaffold(
backgroundColor: Colors.blueGrey[900],
appBar: AppBar(
//backgroundColor: Colors.blueGrey[900],
leading: Builder(
builder: (context) => IconButton(
icon: Icon(Icons.menu_rounded),
onPressed: () => Scaffold.of(context).openDrawer(),
),
),
backgroundColor: Colors.transparent,
automaticallyImplyLeading: true,
title: Text(
"Home Page",
style: TextStyle(color: Colors.white),
),
actions: <Widget>[
//Profile Pic
IconButton(
icon: Icon(Icons.circle, color: Colors.white),
tooltip: 'Comment Icon',
onPressed: () {},
),
MainPopUp(), //IconButton
],
//IconButton
brightness: Brightness.dark,
),
//Current Method of Calling the Drawer:
drawer: MainDrawer(),

Add a leading inside AppBar() and open drawer programatically.
AppBar(
leading: InkWell(
child: Icon(
//your preferred icon
Icons.camera
),
onTap: () {
Scaffold.of(context).openDrawer();
},
),
)

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"),
],
),
));
}
}

flutter:: I have a question about how to use the app top bar

This time I'm making an app top bar in flutter. I wrote code like this.
import 'package:flutter/material.dart';
class VideoAppBar extends StatelessWidget{
const VideoAppBar({Key? key}) : super(key: key);
#override
Widget build(BuildContext context){
return SafeArea(
child: Scaffold(
body: WillPopScope( // <- wraps only the Scaffold body.
child: Center(
),
onWillPop: () {
return Future(() => false);
},
),
appBar: AppBar(
backgroundColor: Colors.white,
title: Text('Very verse',
style: TextStyle(
color: Colors.black,
fontSize: 20,
),),
centerTitle: true,
leading: IconButton(
onPressed: () {
Navigator.pop(context);
},
color: Colors.black,
iconSize: 25,
icon: Icon(Icons.arrow_back),
),
actions: <Widget>[
IconButton(
icon: Icon(Icons.bookmark_outline),
iconSize: 25,
color: Colors.black,
onPressed: () {
print('GD');
}
),
],
),
),
);
}
}
I'd like to put this code simply as a function on several other pages.
AppBar(title:VideoAppBar);
I figured it could be done like this.
But it doesn't go back.
How should I write the code?
Try below Code hope its helpful to you
Create your regular class or your Widget like below:
import 'package:flutter/material.dart';
void main() {
runApp(
MyApp(),
);
}
class MyApp extends StatelessWidget {
bool shouldPop = true;
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: WillPopScope(
onWillPop: () async {
return shouldPop;
},
child: Scaffold(
appBar: appBar(context),
body: Center(
child: Text('Test'),
),
),
),
);
}
}
Create another dart file like appBar.dart and declare your Appbar Widget in dart file. call your widget any file on your need
appBar(BuildContext context) {
return AppBar(
backgroundColor: Colors.white,
title: Text(
'Very verse',
style: TextStyle(
color: Colors.black,
fontSize: 20,
),
),
centerTitle: true,
leading: IconButton(
onPressed: () {
Navigator.pop(context);
},
color: Colors.black,
iconSize: 25,
icon: Icon(Icons.arrow_back),
),
actions: <Widget>[
IconButton(
icon: Icon(Icons.bookmark_outline),
iconSize: 25,
color: Colors.black,
onPressed: () {
print('GD');
}),
],
);
}
For WillPopScope class
For Scaffold class
For AppBar
Your result screen ->

Switch screen in flutter without context in flutter

I have this dart file(app_bar.dart) and am storing Appbars inside it and i have logged_home.dart file where am calling the app_bar.dart from. Now i want to be able to navigate to a new screen when i click next screen it sends me to PostData() while in app_bar.dart.
app_bar.dart:
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:kopala_dictionary/screens/authenticate/login.dart';
import 'package:kopala_dictionary/screens/author/post_data.dart';
import 'package:kopala_dictionary/screens/home/unlogged_home.dart';
//for logged in user
final loggedBar = AppBar(
title: Text('Kopalaz Dictionary'),
backgroundColor: Colors.green,
elevation: 0.0,
actions: <Widget>[
FlatButton.icon(
color: Colors.white,
onPressed: () {
Navigator.push(
context, MaterialPageRoute(builder: (context) => PostData()));
},
icon: Icon(Icons.add),
label: Text(
'Post',
style: TextStyle(color: Colors.white),
)),
],
);
//For unlogged users
final unloggedBar = AppBar(
title: Text('Kopalaz Dictionary'),
backgroundColor: Colors.green,
elevation: 0.0,
);
logged_home.dart:
import 'package:flutter/material.dart';
import 'package:kopala_dictionary/screens/wrapper.dart';
import 'package:kopala_dictionary/services/auth.dart';
import 'package:kopala_dictionary/shared/app_bar.dart';
class LoggedInUserHome extends StatelessWidget {
final AuthService _auth = AuthService();
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.green[10],
appBar: loggedBar,
drawer: Drawer(
child: ListView(
padding: EdgeInsets.zero,
children: <Widget>[
DrawerHeader(
child: Text(
'Kopalationary Menu',
style: TextStyle(color: Colors.white),
),
decoration: BoxDecoration(
color: Colors.green,
),
),
ListTile(
title: Text('Home'),
onTap: () {
Navigator.push(context,
MaterialPageRoute(builder: (context) => Wrapper()));
},
),
ListTile(
title: Text(
'My profile',
),
onTap: () {},
),
ListTile(
title: Text('Logout'),
onTap: () async {
dynamic result = await _auth.logoutUser();
},
),
ListTile(
title: Text(
'About',
),
onTap: () {},
),
],
),
),
body: Center(
child: Text('Development in progress!'),
),
);
}
}
do not forget that in Flutter everything is a widget !
So my advice would be to create functions which returns a widget:
import 'package:flutter/material.dart';
//for logged in user
AppBar loggedBar(BuildContext context) {
return AppBar(
title: Text('Kopalaz Dictionary'),
backgroundColor: Colors.green,
elevation: 0.0,
actions: <Widget>[
FlatButton.icon(
color: Colors.white,
onPressed: () {
Navigator.push(context, MaterialPageRoute(builder: (context) => PostData()));
},
icon: Icon(Icons.add),
label: Text(
'Post',
style: TextStyle(color: Colors.white),
)),
],
);
}
//For unlogged users
AppBar unloggedBar(BuildContext context) {
return AppBar(
title: Text('Kopalaz Dictionary'),
backgroundColor: Colors.green,
elevation: 0.0,
);
}
Do keep in mind that flutter does a lot in the background and it is therefore better practice not to store widget in global variable. If you need to access those widgets from different part of your app you should look into Inherited Widget or other form of state management (see list here).
see below link:
Navigate without context in Flutter with a Navigation Service
https://medium.com/flutter-community/navigate-without-context-in-flutter-with-a-navigation-service-e6d76e880c1c
also, you can use GetX library

Add 2 appbars in flutter

I want my app to have 2 appBars but i don't know how i can add the second one , The first one have this code :
appBar:
AppBar(
title: Text('Tariffo',
style: TextStyle(
color: Colors.white,
fontFamily: 'SignPainter',
fontSize: 45)),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.vertical(
bottom: Radius.circular(30),
),
),
actions: <Widget>[
Padding(
padding: EdgeInsets.only(right: 10),
),
IconButton(
icon: Icon(Icons.center_focus_weak),
onPressed: () async {
String scaning = await BarcodeScanner.scan();
setState(() {
qrResult = scaning;
});
},
),
IconButton(
icon: Icon(
Icons.perm_identity,
color: Colors.white,
),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => UserPage()),
);
}),
And the second one have this code:
appBar: AppBar(title: const Text('Bottom App Bar')),
floatingActionButtonLocation:
FloatingActionButtonLocation.centerDocked,
floatingActionButton: FloatingActionButton(
child: const Icon(Icons.add), onPressed: () {},),
bottomNavigationBar: BottomAppBar(
shape: CircularNotchedRectangle(),
notchMargin: 4.0,
child: new Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
IconButton(icon: Icon(Icons.menu), onPressed: () {},),
IconButton(icon: Icon(Icons.search), onPressed: () {},),
],
),
),
);
}
So how can i add the second one to not get an error? Beacuse i tried to erase the first part with appbar: Appbar and i get a lot o errors
Edit:
As Derek pointed out you should not place two Scaffolds in your App.
A different solution could be to place the first AppBar as usual in the appBar property of your Scaffold and the second as a first children in a Column.
This would look like:
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
backgroundColor: Colors.blue,
title: Text("First appbar"),
),
body: Column(
children: [
AppBar(
backgroundColor: Colors.red,
title: Text("Second appbar"),
),
HomePage()
],
),
),
);
}
}
class HomePage extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Container(
color: Colors.yellow,
child: Text("Content"),
);
}
}
---------------------------
Old Answer:
Actually this is really simple.
You create your Scaffold in which you put the first AppBar as usual.
As the body of this Scaffold you put a second Scaffold in which you place your second AppBar.
The result would look like:
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
backgroundColor: Colors.blue,
title: Text("First appbar"),
),
body: Scaffold(
appBar: AppBar(
backgroundColor: Colors.red,
title: Text("Second appbar"),
),
),
),
);
}
}

change drawer item icon to right flutter

I used drawer in the flutter, and I user end drawer to change the direction the drawer,
but I need also change the direction of drawer item icon to right flutter, how can I do it?
You can achieve this using ListTile widgets
Try this way
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
void main() => runApp( HomeApp());
class HomeApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
// TODO: implement build
return new MaterialApp(
theme: new ThemeData(
primarySwatch: Colors.deepPurple,
brightness: Brightness.light,
accentColor: Colors.red),
home: new HomePage(),
);
}
}
class HomePage extends StatefulWidget {
#override
_HomePageScreen createState() => _HomePageScreen();
}
class _HomePageScreen extends State<HomePage> {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Home"),
),
endDrawer: Drawer(
child: ListView(
padding: EdgeInsets.all(0.0),
children: <Widget>[
UserAccountsDrawerHeader(
accountName: Text("Nilesh Rathod"),
accountEmail: Text("nilesh#gmail.com"),
currentAccountPicture: CircleAvatar(
backgroundColor: Colors.white,
child: Text("Nilu"),
),
otherAccountsPictures: <Widget>[
CircleAvatar(
backgroundColor: Colors.white,
child: Text("Pilu"),
),
],
),
ListTile(
title: Text("Home"),
trailing: Icon(Icons.new_releases),
),
Divider(),
ListTile(
title: Text("Profile"),
trailing: Icon(Icons.person),
onTap: () => {},
),
Divider(),
ListTile(
title: Text("Tab Layout"),
trailing: Icon(Icons.person),
onTap: () => {},
),
Divider(),
ListTile(
title: Text("Comman View Demo"),
trailing: Icon(Icons.person),
onTap: () => {},
),
Divider(),
ListTile(
title: Text("Close"),
trailing: Icon(Icons.close),
onTap: () => Navigator.of(context).pop(),
),
],
),
),
body: Center(
child: Text("Home Screen"),
),
);
}
}
SAMPLE CODE
Make use of ListTile trailing property
ListTile(
title: Text("text"),
trailing: Icon(Icons.account),
onTap:null,
),