Reputation: 43
When I created drawer layout following the Add a Drawer to a screen docs, it works OK. However, I have a problem, this is menu Icon.
In Android, I setup drawer layout with DrawerToggle and when I open drawer, menu icon is going to change to arrow icon and when I close drawer, arrow icon is going to change to menu icon.
In Flutter, it do not work as above.
If you understand my problem, please help me. I have search a lot, but not found solution. So I want to ask everyone. Thankyou so much.
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
final appTitle = 'Drawer Demo';
@override
Widget build(BuildContext context) {
return MaterialApp(
title: appTitle,
home: MyHomePage(title: appTitle),
);
}
}
class MyHomePage extends StatelessWidget {
final String title;
MyHomePage({Key key, this.title}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text(title)),
body: Center(child: Text('My Page!')),
drawer: Drawer(
// Add a ListView to the drawer. This ensures the user can scroll
// through the options in the Drawer if there isn't enough vertical
// space to fit everything.
child: ListView(
// Important: Remove any padding from the ListView.
padding: EdgeInsets.zero,
children: <Widget>[
DrawerHeader(
child: Text('Drawer Header'),
decoration: BoxDecoration(
color: Colors.blue,
),
),
ListTile(
title: Text('Item 1'),
onTap: () {
// Update the state of the app
// ...
// Then close the drawer
Navigator.pop(context);
},
),
ListTile(
title: Text('Item 2'),
onTap: () {
// Update the state of the app
// ...
// Then close the drawer
Navigator.pop(context);
},
),
],
),
),
);
}
}
Upvotes: 3
Views: 6765
Reputation: 618
Below I attach a snippet of my code that I think is the easiest way to have a custom hamburger icon. The main part of the code is to use leading:!
return Scaffold(
backgroundColor: Colors.white,
appBar: AppBar(
backgroundColor: Colors.transparent,
elevation: 0.0,
leading: Builder(
builder: (context) => IconButton(
icon: Icon(
Icons.sort,
color: Colors.black54,
),
onPressed: () => Scaffold.of(context).openDrawer(),
tooltip:
MaterialLocalizations.of(context).openAppDrawerTooltip,
)),
),
drawer: Drawer(
child: ListView(
padding: EdgeInsets.zero,
children: <Widget>[
DrawerHeader(
decoration: BoxDecoration(
color: Colors.blue,
),
child: Text('App'),
),
ListTile(
title: Text('Item 1'),
onTap: () {
Navigator.pop(context);
},
),
ListTile(
title: Text('Item 2'),
onTap: () {
Navigator.pop(context);
},
),
],
),
),)
Upvotes: 0
Reputation: 3987
Use StateFulWidget
so you can access setState
method to change icon
In your state
class
Define a Global Key
final GlobalKey<ScaffoldState> _key = GlobalKey();
Define a boolean
to check whether Drawer
is open.
bool _isDrawerOpen = false;
Add these to your state
class
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Title'),
leading: IconButton(
icon: _isDrawerOpen ? Icon(Icons.menu) : Icon(Icons.arrow_back),
onPressed: onPressed,
),
),
drawer: WillPopScope(child: Drawer(), onWillPop: onPop),
body: //body
key: this._key,
);
}
void onPressed() {
if (!_isDrawerOpen) {
this._key.currentState.openDrawer();
} else {
Navigator.pop(context);
}
setState(() {
_isDrawerOpen = !_isDrawerOpen;
});
}
void onPop() {
if (_isDrawerOpen) {
setState(() {
_isDrawerOpen = false;
});
}
Navigator.pop(context);
}
Upvotes: 1
Reputation: 3090
To change hamburger icon while drawer open and also to display drawer below app bar:
I have declared "METHOD 1" and "METHOD 2" in my code which are in comments.
"METHOD 1" allows to open drawer and change icon with drawer controller callback.
"METHOD 2" allows to open drawer when we click hamburger icon The problem is if we used can't click on hamburger icon when use drawer controller.
import 'package:flutter/material.dart';
class MyNavDrawerController extends StatefulWidget {
createState() {
return StateKeeper();
}
}
class StateKeeper extends State<MyNavDrawerController> {
// Declare a new variable which will increment on FAB tap
final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();
final appBarColor = const Color(0xFFd2527f);
var myIcon = new Icon(Icons.list);
DrawerCallback drawerCallback(bool status) {
Fluttertoast.showToast(
msg: "Drawer " + status.toString(),
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.CENTER,
timeInSecForIos: 1,
backgroundColor: appBarColor,
textColor: Colors.white,
fontSize: 14.0);
setState(() {
setMenuIcon(status);
});
}
@override
void initState() {
// TODO: implement initState
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
key: _scaffoldKey,
primary: true,
appBar: AppBar(
title: Text("Parent Scaffold"),
leading: new IconButton(icon: myIcon,
onPressed:(){
_scaffoldKey.currentState.openDrawer();
}
)
),
// METHOD 1
/*body: DrawerController(
child: Drawer(
child: ListView(
padding: EdgeInsets.zero,
children: <Widget>[
DrawerHeader(
child: Text('Andy Rubin'),
decoration: BoxDecoration(color: Colors.blue),
),
ListTile(
title: Text('Home'),
onTap: () {
setState(() {
Navigator.pop(context);
});
},
),
ListTile(
title: Text('About us'),
onTap: () {
Navigator.pop(context);
Fluttertoast.showToast(
msg: "About us clicked! :)",
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.CENTER,
timeInSecForIos: 1,
backgroundColor: Colors.red,
textColor: Colors.white,
fontSize: 16.0);
},
),
ListTile(
title: Text('Notifications'),
onTap: () {
Navigator.pop(context);
Fluttertoast.showToast(
msg: "Notifications clicked! :)",
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.CENTER,
timeInSecForIos: 1,
backgroundColor: Colors.blue,
textColor: Colors.white,
fontSize: 18.0);
},
)
],
),
),
alignment: DrawerAlignment.start, drawerCallback: drawerCallback
),*/
// METHOD 2
/*body: Scaffold(
key: _scaffoldKey,
drawer: Drawer(
child: ListView(
padding: EdgeInsets.zero,
children: <Widget>[
DrawerHeader(
child: Text('Andy Rubin'),
decoration: BoxDecoration(color: Colors.blue),
),
ListTile(
title: Text('Home'),
onTap: () {
Fluttertoast.showToast(
msg: "Home clicked! :)",
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.CENTER,
timeInSecForIos: 1,
backgroundColor: appBarColor,
textColor: Colors.white,
fontSize: 14.0);
setState(() {
Navigator.pop(context);
});
},
),
ListTile(
title: Text('About us'),
onTap: () {
Navigator.pop(context);
Fluttertoast.showToast(
msg: "About us clicked! :)",
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.CENTER,
timeInSecForIos: 1,
backgroundColor: Colors.red,
textColor: Colors.white,
fontSize: 16.0);
},
),
ListTile(
title: Text('Notifications'),
onTap: () {
Navigator.pop(context);
Fluttertoast.showToast(
msg: "Notifications clicked! :)",
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.CENTER,
timeInSecForIos: 1,
backgroundColor: Colors.blue,
textColor: Colors.white,
fontSize: 18.0);
},
)
],
),
),
)*/
);
}
void setMenuIcon(bool isDrawerOpen){
if(isDrawerOpen){
myIcon = new Icon(Icons.list);
}else{
myIcon = new Icon(Icons.arrow_back);
}
}
}
Upvotes: 0