Skip to content

Commit

Permalink
drawers support added
Browse files Browse the repository at this point in the history
  • Loading branch information
n0vah committed May 5, 2019
1 parent dcb31aa commit 6bfd5ac
Show file tree
Hide file tree
Showing 11 changed files with 226 additions and 24 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## [1.0.0] - 2019-04-22

* initial release

## [1.0.7] - 2019-05-05

* drawers support added
33 changes: 32 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ clearStackAfterTapOnCurrentTab: false
```
When you navigate to another route within nested navigator, you can hide *BottomNavigatorsBar* for specific route, just add **hideNavTabBar: true** to route arguments:
```dart
Navigator.of(context).pushNamed(
Navigator.of(context).pushNamed(
Routes.red,
arguments: {
hideNavTabBar: true,
Expand Down Expand Up @@ -141,3 +141,34 @@ class _AppState extends State<App> {
}
}
```
You can use *Drawer* instead of *BottomNavigationBar*, use **drawer** or **endDrawer** for this:
```dart
drawer: (items, selectedItemKey, selectNavigator) => Drawer(
child: ListView(
children: items.entries
.map((entry) => ListTile(
title: Text(
entry.value.text,
style: TextStyle(
color: entry.key == selectedItemKey
? Colors.blue
: null,
),
),
trailing: Icon(
entry.value.icon,
color:
entry.key == selectedItemKey ? Colors.blue : null,
),
onTap: () => selectNavigator(entry.key),
))
.toList(),
),
),
```
Also you can open drawers from your pages:
```dart
NestedNavigatorsBlocProvider.of(context).actionWithScaffold(
(scaffoldState) => scaffoldState.openDrawer(),
);
```
22 changes: 22 additions & 0 deletions example/ios/Podfile.lock
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
PODS:
- Flutter (1.0.0)
- nested_navigators (0.0.1):
- Flutter

DEPENDENCIES:
- Flutter (from `.symlinks/flutter/ios`)
- nested_navigators (from `.symlinks/plugins/nested_navigators/ios`)

EXTERNAL SOURCES:
Flutter:
:path: ".symlinks/flutter/ios"
nested_navigators:
:path: ".symlinks/plugins/nested_navigators/ios"

SPEC CHECKSUMS:
Flutter: 9d0fac939486c9aba2809b7982dfdbb47a7b0296
nested_navigators: fdadb3e96b2b20ddd5eaf4e2370a7ae194b2e952

PODFILE CHECKSUM: aff02bfeed411c636180d6812254b2daeea14d09

COCOAPODS: 1.5.3
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>BuildSystemType</key>
<string>Original</string>
</dict>
</plist>
31 changes: 24 additions & 7 deletions example/lib/pages/blue_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@ class BluePage extends StatelessWidget {
text: "open new page",
onPressed: () {
Navigator.of(context).pushNamed(
Routes.blue,
arguments: value + 1,
Routes.blue,
arguments: value + 1,
);
},
),
Expand All @@ -50,7 +50,26 @@ class BluePage extends StatelessWidget {
_item(
text: "select green tab",
onPressed: () {
NestedNavigatorsBlocProvider.of(context).select(NestedNavItemKey.green);
NestedNavigatorsBlocProvider.of(context)
.select(NestedNavItemKey.green);
},
),
_divider(),
_item(
text: "open left drawer",
onPressed: () {
NestedNavigatorsBlocProvider.of(context).actionWithScaffold(
(scaffoldState) => scaffoldState.openDrawer(),
);
},
),
_divider(),
_item(
text: "open right drawer",
onPressed: () {
NestedNavigatorsBlocProvider.of(context).actionWithScaffold(
(scaffoldState) => scaffoldState.openEndDrawer(),
);
},
),
],
Expand All @@ -59,8 +78,7 @@ class BluePage extends StatelessWidget {
);
}

_item({String text, Function() onPressed}) =>
FlatButton(
_item({String text, Function() onPressed}) => FlatButton(
child: Text(
text,
textAlign: TextAlign.center,
Expand All @@ -69,8 +87,7 @@ class BluePage extends StatelessWidget {
onPressed: onPressed,
);

_divider() =>
Flexible(
_divider() => Flexible(
child: Container(
margin: EdgeInsets.symmetric(vertical: 8),
color: Colors.white,
Expand Down
37 changes: 36 additions & 1 deletion example/lib/pages/root_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,20 @@ class _RootPageState extends State<RootPage> {
),
},
generateRoute: Routes.generateRoute,
buildBottomNavigationItem: (key, item, selected) => BottomNavigationBarItem(
drawer: (items, selectedItemKey, selectNavigator) => Drawer(
child: ListView(
children:
_buildDrawersItems(items, selectedItemKey, selectNavigator),
),
),
endDrawer: (items, selectedItemKey, selectNavigator) => Drawer(
child: ListView(
children:
_buildDrawersItems(items, selectedItemKey, selectNavigator),
),
),
buildBottomNavigationItem: (key, item, selected) =>
BottomNavigationBarItem(
icon: Icon(
item.icon,
color: Colors.blue,
Expand All @@ -46,4 +59,26 @@ class _RootPageState extends State<RootPage> {
),
);
}

List<ListTile> _buildDrawersItems(
Map<NestedNavItemKey, NestedNavigatorItem> items,
NestedNavItemKey selectedItemKey,
Function(NestedNavItemKey) selectNavigator,
) {
return items.entries
.map((entry) => ListTile(
title: Text(
entry.value.text,
style: TextStyle(
color: entry.key == selectedItemKey ? Colors.blue : null,
),
),
trailing: Icon(
entry.value.icon,
color: entry.key == selectedItemKey ? Colors.blue : null,
),
onTap: () => selectNavigator(entry.key),
))
.toList();
}
}
2 changes: 1 addition & 1 deletion example/pubspec.lock
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ packages:
path: ".."
relative: true
source: path
version: "1.0.4"
version: "1.0.7"
path:
dependency: transitive
description:
Expand Down
11 changes: 11 additions & 0 deletions lib/nested_nav_bloc.dart
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ class NestedNavigatorsBloc<T> {

final _tabBarVisibilityController = StreamController<bool>.broadcast();

final _actionWithScaffoldController =
StreamController<Function(ScaffoldState scaffoldState)>.broadcast();

Stream<T> get outSelectTab => _selectNavigatorController.stream;

Stream<MapEntry<T, Function(NavigatorState navigator)>>
Expand All @@ -25,6 +28,9 @@ class NestedNavigatorsBloc<T> {

Stream<bool> get outTabBarVisibility => _tabBarVisibilityController.stream;

Stream<Function(ScaffoldState scaffoldState)> get outActionWithScaffold =>
_actionWithScaffoldController.stream;

/// Select nested navigator
select(T key) {
if (key != _selectedNavigatorKey) {
Expand All @@ -46,9 +52,14 @@ class NestedNavigatorsBloc<T> {
}
}

actionWithScaffold(Function(ScaffoldState scaffoldState) action) {
_actionWithScaffoldController.sink.add(action);
}

void dispose() {
_selectNavigatorController.close();
_selectNavigatorAndNavigateController.close();
_tabBarVisibilityController.close();
_actionWithScaffoldController.close();
}
}
97 changes: 84 additions & 13 deletions lib/nested_navigators.dart
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:nested_navigators/nested_nav_bloc.dart';
import 'package:nested_navigators/nested_nav_bloc_provider.dart';
Expand Down Expand Up @@ -29,6 +30,9 @@ class NestedNavigators<T> extends StatefulWidget {
BottomNavigationBarItem Function(
T key, NestedNavigatorItem item, bool selected)
buildBottomNavigationItem,
this.drawer,
this.endDrawer,
this.drawerDragStartBehavior = DragStartBehavior.down,
this.buildCustomBottomNavigationItem,
this.bottomNavigationBarTheme,
this.showBottomNavigationBar = true,
Expand Down Expand Up @@ -94,7 +98,46 @@ class NestedNavigators<T> extends StatefulWidget {
/// ))
/// ```
final BottomNavigationBarItem Function(
T key, NestedNavigatorItem item, bool selected) buildBottomNavigationItem;
T key,
NestedNavigatorItem item,
bool selected,
) buildBottomNavigationItem;

/// A panel displayed to the side of the [body], often hidden on mobile
/// devices. Swipes in from right-to-left ([TextDirection.ltr]) or
/// left-to-right ([TextDirection.rtl])
///
/// Typically a [Drawer].
final Widget Function(
Map<T, NestedNavigatorItem> items,
T selectedItemKey,
Function(T) selectNavigator,
) drawer;

/// A panel displayed to the side of the [body], often hidden on mobile
/// devices. Swipes in from either left-to-right ([TextDirection.ltr]) or
/// right-to-left ([TextDirection.rtl])
///
/// Typically a [Drawer].
final Widget Function(
Map<T, NestedNavigatorItem> items,
T selectedItemKey,
Function(T) selectNavigator,
) endDrawer;

/// Determines the way that drag start behavior is handled.
///
/// If set to [DragStartBehavior.start], the drag behavior used for opening
/// and closing a drawer will begin upon the detection of a drag gesture.
/// If set to [DragStartBehavior.down] it will begin when a down event is
/// first detected.
///
/// In general, setting this to [DragStartBehavior.start] will make drag
/// animation smoother and setting it to [DragStartBehavior.down] will make
/// drag behavior feel slightly more reactive.
///
/// By default, the drag start behavior is [DragStartBehavior.down].
final DragStartBehavior drawerDragStartBehavior;

/// Use this builder if [BottomNavigationBarItem] is not enough for you, and you want to use your own tab item design.
///
Expand All @@ -119,8 +162,11 @@ class NestedNavigators<T> extends StatefulWidget {
/// ),
/// ),
///```
final Widget Function(T key, NestedNavigatorItem item, bool selected)
buildCustomBottomNavigationItem;
final Widget Function(
T key,
NestedNavigatorItem item,
bool selected,
) buildCustomBottomNavigationItem;

/// Define your owen theme of bottom navigation bar with splashColor for using different ripple effect color, or selected state icon and text color.
///
Expand Down Expand Up @@ -157,7 +203,6 @@ class NestedNavigators<T> extends StatefulWidget {

static T _defaultInitialSelectedNavigatorKey<T>(Iterable<T> keys) {
int size = keys.length;
print((size / 2).floor() + 1);
return size % 2 == 0 ? keys.first : keys.elementAt((size / 2).floor());
}

Expand All @@ -168,6 +213,7 @@ class NestedNavigators<T> extends StatefulWidget {
class _NestedNavigatorsState<T> extends State<NestedNavigators> {
NestedNavigatorsBloc<T> _bloc;
bool _hasBlocProviderInTree = false;
GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey();

Map<T, NestedNavigatorItem> get _items => widget.items;

Expand All @@ -193,12 +239,18 @@ class _NestedNavigatorsState<T> extends State<NestedNavigators> {
// Set the bottom navigation bar visibility when nested navigator selected
// by using NestedNavigatorsBloc.select() or NestedNavigatorsBloc.selectAndNavigate()
_bloc.outSelectTab.listen(
(key) => _bloc.setTabBarVisibility(_items[key].navTabBarVisible));
(key) => _bloc.setTabBarVisibility(_items[key].navTabBarVisible),
);

// Listen queries from widget which was added to widget tree with using root navigator,
// but which is child of NestedNavigatorsBlocProvider, it's will work when app widget is child of NestedNavigatorsBlocProvider
_bloc.outSelectTabAndNavigate
.listen((entry) => entry.value(_getNavigatorState(entry.key)));
_bloc.outSelectTabAndNavigate.listen(
(entry) => entry.value(_getNavigatorState(entry.key)),
);

_bloc.outActionWithScaffold.listen(
(action) => action(_scaffoldKey.currentState),
);
}

@override
Expand All @@ -217,6 +269,22 @@ class _NestedNavigatorsState<T> extends State<NestedNavigators> {
stream: _bloc.outSelectTab,
initialData: _bloc.selectedNavigatorKey,
builder: (_, snapshot) => Scaffold(
key: _scaffoldKey,
drawer: widget.drawer != null
? widget.drawer(
_items,
_bloc.selectedNavigatorKey,
(key) => _bloc.select(key),
)
: null,
endDrawer: widget.endDrawer != null
? widget.endDrawer(
_items,
_bloc.selectedNavigatorKey,
(key) => _bloc.select(key),
)
: null,
drawerDragStartBehavior: widget.drawerDragStartBehavior,
body: Stack(
children: _items.keys
.map((key) => _buildNavigator(key, snapshot.data))
Expand Down Expand Up @@ -246,12 +314,15 @@ class _NestedNavigatorsState<T> extends State<NestedNavigators> {
);

List<BottomNavigationBarItem> getBottomNavigatorBarItems() {
List<BottomNavigationBarItem> items = new List();
_items.forEach(
(key, tabItem) => items.add(widget.buildBottomNavigationItem(
key, tabItem, _bloc.selectedNavigatorKey == key)),
);
return items;
return _items.entries
.map(
(entry) => widget.buildBottomNavigationItem(
entry.key,
entry.value,
_bloc.selectedNavigatorKey == entry.key,
),
)
.toList();
}

Widget _buildCustomBottomNavigatorBar() {
Expand Down
Loading

0 comments on commit 6bfd5ac

Please sign in to comment.