sidemenudownside
this project is about a customized flutter drawer.
structure
this project is created with dart
and flutter 1.25.0-4.0.pre
.
class sidemenudownside
is container of sidemenucontent
.
sidemenudownside
is a skeleton, hub to combine another component together. it is written fileside_menu_down_side.dart
sidemenucontent
contains logic about how to displaymenu items
. it is written in fileside_menu_content.dart
sidemenuholder
contains adatasource
for screen list (a list of widget). it is written in fileside_menu_holder.dart
sidemenuscreencontainer
will help us to relayout, trigger animation, display current screen. it is written in fileside_menu_screen_container.dart
how to use
⚠️⚠️⚠️ outdated, will be updated soon! but i already added comment for each important block of codes.
- update your
main.dart
. here is your newmain.dart
content:
import 'package:flutter/material.dart';
import 'package:side_menu_down_side/navigation_center.dart';
import 'package:side_menu_down_side/side_menu_down_side/side_menu_down_side.dart';
// another your desired import ...
void main() {
runapp(myapp());
}
class myapp extends statelesswidget {
// this widget is the root of your application.
@override
widget build(buildcontext context) {
// update appcontext for later usage
navigationcenter.shared.appcontext = context;
return materialapp(
title: 'sidemenu downside',
theme: themedata(
primaryswatch: colors.green,
visualdensity: visualdensity.adaptiveplatformdensity,
),
home: sidemenudownside(), // <--- here is our sidemenudownside
);
}
}
- take a look at class
sidemenuholder
(a singleton) inlibside_menu_down_sideside_menu_holder.dart
,
this class has a list of_menuitem
. that stores data of eachrootscreen
in menu.
list<_menuitem> _menus = ... // this is place where we display menu items.
- here is our
_menuitem
andheaderinfo
class to contain data ofsidemenucontent
class _menuitem {
final string name; // menu item's name
final icondata icon; // icon of menu item
final bool isheader;
final widget rootscreen; // scren to be displayed (a scaffold - widget)
_menuitem({this.name, this.icon, this.isheader, this.rootscreen});
}
class headerinfo {
final icondata image;
final string name;
final string subinfo;
headerinfo({this.image, this.name, this.subinfo});
}
- you can adjust the
position, size
ofcontent
(ourrootscreen
, that is displayed after click menu item).
in fileside_menu_down_side.dart
// these functions will be called every time widget(content/screen) has to be re-rendered
matrix4 _gettransform(buildcontext ctx) {
var width = mediaquery.of(context).size.width; // screenwidth
// if menu is displayed, move content to the right by 40% of screen width
_transform =
matrix4.translationvalues(width * (_ismenuopened ? 0.4 : 0), 0.0, 0.0);
return _transform;
}
double _getheight(buildcontext ctx) {
var height = mediaquery.of(context).size.height;
// if menu is displayed, scale down content's height (of rootscreen) to 75% of screen height (original)
_height = height * (_ismenuopened ? 0.75 : 1);
return _height;
}
double _getwidth(buildcontext ctx) {
var width = mediaquery.of(context).size.width;
// if menu is displayed, scale down content's width (of rootscreen) to 75% of screen width (original)
_width = width * (_ismenuopened ? 0.75 : 1);
return _width;
}
- you can adjust the open-close animation speed in
side_menu_down_side.dart
:
animatedcontainer(
// use the properties stored in the state class.
width: _getwidth(context),
height: _getheight(context),
transform: _gettransform(context),
// define how long the animation should take.
duration: duration(milliseconds: 500), // <-- here is animation time
// provide an optional curve to make the animation feel smoother.
curve: curves.fastoutslowin,
- finally, check the example rootscreen(the screen which is opened from sidemenu, or placed in sidemenu), like below:
class rootscreen1 extends statelesswidget {
@override
widget build(buildcontext context) {
// update current text (a "context" of root screen) to perform a navigation like real drawer
navigationcenter.shared.currentcontext = context; // <- here to keep a refer to your current "root screen"'s build context for later usage
return scaffold(
appbar: appbar(
leading:
// you can make this button become a customized button for appbar
flatbutton(
onpressed: () {
sidemenuholder.shared.onmenubuttonclicklistener(); // <- you can call this function anywhere to open the sidemenu
},
child: icon(
icons.menu,
color: colors.white,
),
),
title: text('rootscreen1'),
titlespacing: 0,
),
body: center(
child: flatbutton(
onpressed: () {
navigationcenter.shared.navigate(subscreen1()); // <- this is how i navigate in this project
},
child: text('screen 1'),
),
),
);
}
}
- and, this is how your subscreen appbar is:
class subscreen1 extends statelesswidget {
@override
widget build(buildcontext context) {
return scaffold(
appbar: appbar(
leading: flatbutton(
onpressed: () {
navigationcenter.shared.back(); // <- this how i navigate back, or pop,... in this project
},
child: icon(
icons.arrow_back,
color: colors.white,
),
),
title: text('subscreen1'),
),
body: center(
child: text('sub screen 1'),
),
);
}
}
- you can also change the logic of navigation in class navigationcenter to has “real” push animation when navigate to new screen.
import 'package:flutter/cupertino.dart'; // for this cupertinopageroute
import 'package:flutter/material.dart'; // for this materialpageroute
class navigationcenter {
buildcontext appcontext;
buildcontext currentcontext;
statefulwidget currentscreen;
void navigate(widget newscreen, [bool fromappcontext = false]) {
if (currentcontext == null) return;
navigator.push(
fromappcontext ? appcontext : (currentcontext ?? appcontext),
// materialpageroute(builder: (context) => newscreen), // (1) - slide upward
cupertinopageroute(builder: (context) => newscreen)); // (2) - push left
}
...
}
Comments are closed.