Skip to content

Instantly share code, notes, and snippets.

@zonble
Created November 5, 2019 02:54
Show Gist options
  • Save zonble/f32d78becfd5baa88f78fd445d3d214c to your computer and use it in GitHub Desktop.
Save zonble/f32d78becfd5baa88f78fd445d3d214c to your computer and use it in GitHub Desktop.
Menu Navigation
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'menu.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
String _selectedId;
GlobalKey<NavigatorState> _key = GlobalKey<NavigatorState>();
@override
Widget build(BuildContext context) {
var rootMenu = [
MenuFolder(title: "玩具", id: "tody", children: <MenuNode>[
MenuItem(title: "鋼彈", id: "gundam"),
MenuItem(title: "芭比", id: "barbie"),
]),
MenuFolder(title: "食物", id: "food", children: <MenuNode>[
MenuItem(title: "雞蛋", id: "egg"),
MenuItem(title: "牛奶", id: "milk"),
]),
];
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
drawer: Drawer(
child: Navigator(
key: _key,
initialRoute: "/",
onGenerateRoute: (RouteSettings settings) {
WidgetBuilder builder;
if (settings.name == '/') {
builder = (BuildContext context) => Menu(
title: "選單",
menuItems: rootMenu,
onSelectItem: (id) => setState(() {
_selectedId = id;
}),
);
}
return CupertinoPageRoute(builder: builder, settings: settings);
},
),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text('Selected id is:'),
Text(_selectedId ?? "Not selected"),
],
),
),
);
}
}
class Menu extends StatefulWidget {
final String title;
final List<MenuNode> menuItems;
final Function(String string) onSelectItem;
Menu({
Key key,
this.title,
this.menuItems,
this.onSelectItem,
}) : super(key: key);
@override
State<StatefulWidget> createState() => MenuState();
}
class MenuState extends State<Menu> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: ListView.builder(
itemBuilder: (context, index) {
final item = widget.menuItems[index];
// print(item);
if (item is MenuSeparator) {
return Divider();
}
return ListTile(
title: Text(item.title),
trailing:
item is MenuFolder ? Icon(Icons.arrow_forward_ios) : null,
onTap: () {
print(item);
if (item is MenuFolder) {
print(item.children);
final route = CupertinoPageRoute(
builder: (context) => Menu(
title: item.title,
menuItems: item.children,
onSelectItem: widget.onSelectItem,
));
Navigator.of(context).push(route);
return;
}
widget.onSelectItem(item.id);
},
);
},
itemCount: widget.menuItems.length),
);
}
}
abstract class MenuNode {
String get id;
String get title;
}
class MenuItem implements MenuNode {
final String id;
final String title;
MenuItem({this.id, this.title});
}
class MenuSeparator implements MenuNode {
String get id => "";
String get title => "";
}
class MenuFolder implements MenuNode {
final String id;
final String title;
final List<MenuNode> children;
MenuFolder({this.id, this.title, this.children});
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment