From fecfa45a2964589947fd2fd5eb9ddd224bc91921 Mon Sep 17 00:00:00 2001 From: Thibault Deckers Date: Fri, 13 May 2022 13:38:25 +0900 Subject: [PATCH] improved nav bar visibility --- lib/widgets/collection/collection_grid.dart | 70 +++++++++++-------- .../filter_grids/common/filter_grid_page.dart | 57 +++++++++------ lib/widgets/navigation/nav_bar/floating.dart | 27 +++++-- lib/widgets/navigation/nav_bar/nav_bar.dart | 2 + 4 files changed, 98 insertions(+), 58 deletions(-) diff --git a/lib/widgets/collection/collection_grid.dart b/lib/widgets/collection/collection_grid.dart index c4b43408d..347e1acac 100644 --- a/lib/widgets/collection/collection_grid.dart +++ b/lib/widgets/collection/collection_grid.dart @@ -350,37 +350,45 @@ class _CollectionScrollViewState extends State<_CollectionScrollView> { Widget _buildDraggableScrollView(ScrollView scrollView, CollectionLens collection) { return ValueListenableBuilder( valueListenable: widget.appBarHeightNotifier, - builder: (context, appBarHeight, child) => Selector( - selector: (context, mq) => mq.effectiveBottomPadding, - builder: (context, mqPaddingBottom, child) { - return Selector, List>( - selector: (context, layout) => layout.sectionLayouts, - builder: (context, sectionLayouts, child) { - return DraggableScrollbar( - backgroundColor: Colors.white, - scrollThumbSize: Size(avesScrollThumbWidth, avesScrollThumbHeight), - scrollThumbBuilder: avesScrollThumbBuilder( - height: avesScrollThumbHeight, - backgroundColor: Colors.white, - ), - controller: widget.scrollController, - crumbsBuilder: () => _getCrumbs(sectionLayouts), - padding: EdgeInsets.only( - // padding to keep scroll thumb between app bar above and nav bar below - top: appBarHeight, - bottom: mqPaddingBottom, - ), - labelTextBuilder: (offsetY) => CollectionDraggableThumbLabel( - collection: collection, - offsetY: offsetY, - ), - crumbTextBuilder: (label) => DraggableCrumbLabel(label: label), - child: scrollView, - ); - }, - ); - }, - ), + builder: (context, appBarHeight, child) { + return Selector( + selector: (context, mq) => mq.effectiveBottomPadding, + builder: (context, mqPaddingBottom, child) { + return Selector( + selector: (context, s) => s.showBottomNavigationBar, + builder: (context, showBottomNavigationBar, child) { + final navBarHeight = showBottomNavigationBar ? AppBottomNavBar.height : 0; + return Selector, List>( + selector: (context, layout) => layout.sectionLayouts, + builder: (context, sectionLayouts, child) { + return DraggableScrollbar( + backgroundColor: Colors.white, + scrollThumbSize: Size(avesScrollThumbWidth, avesScrollThumbHeight), + scrollThumbBuilder: avesScrollThumbBuilder( + height: avesScrollThumbHeight, + backgroundColor: Colors.white, + ), + controller: widget.scrollController, + crumbsBuilder: () => _getCrumbs(sectionLayouts), + padding: EdgeInsets.only( + // padding to keep scroll thumb between app bar above and nav bar below + top: appBarHeight, + bottom: navBarHeight + mqPaddingBottom, + ), + labelTextBuilder: (offsetY) => CollectionDraggableThumbLabel( + collection: collection, + offsetY: offsetY, + ), + crumbTextBuilder: (label) => DraggableCrumbLabel(label: label), + child: scrollView, + ); + }, + ); + }, + ); + }, + ); + }, ); } diff --git a/lib/widgets/filter_grids/common/filter_grid_page.dart b/lib/widgets/filter_grids/common/filter_grid_page.dart index 5f702d7be..b82954061 100644 --- a/lib/widgets/filter_grids/common/filter_grid_page.dart +++ b/lib/widgets/filter_grids/common/filter_grid_page.dart @@ -512,28 +512,41 @@ class _FilterScrollView extends StatelessWidget { } Widget _buildDraggableScrollView(ScrollView scrollView) { - return Selector( - selector: (context, mq) => mq.effectiveBottomPadding, - builder: (context, mqPaddingBottom, child) => DraggableScrollbar( - backgroundColor: Colors.white, - scrollThumbSize: Size(avesScrollThumbWidth, avesScrollThumbHeight), - scrollThumbBuilder: avesScrollThumbBuilder( - height: avesScrollThumbHeight, - backgroundColor: Colors.white, - ), - controller: scrollController, - padding: EdgeInsets.only( - // padding to keep scroll thumb between app bar above and nav bar below - top: appBarHeightNotifier.value, - bottom: mqPaddingBottom, - ), - labelTextBuilder: (offsetY) => FilterDraggableThumbLabel( - sortFactor: sortFactor, - offsetY: offsetY, - ), - crumbTextBuilder: (offsetY) => const SizedBox(), - child: scrollView, - ), + return ValueListenableBuilder( + valueListenable: appBarHeightNotifier, + builder: (context, appBarHeight, child) { + return Selector( + selector: (context, mq) => mq.effectiveBottomPadding, + builder: (context, mqPaddingBottom, child) { + return Selector( + selector: (context, s) => s.showBottomNavigationBar, + builder: (context, showBottomNavigationBar, child) { + final navBarHeight = showBottomNavigationBar ? AppBottomNavBar.height : 0; + return DraggableScrollbar( + backgroundColor: Colors.white, + scrollThumbSize: Size(avesScrollThumbWidth, avesScrollThumbHeight), + scrollThumbBuilder: avesScrollThumbBuilder( + height: avesScrollThumbHeight, + backgroundColor: Colors.white, + ), + controller: scrollController, + padding: EdgeInsets.only( + // padding to keep scroll thumb between app bar above and nav bar below + top: appBarHeight, + bottom: navBarHeight + mqPaddingBottom, + ), + labelTextBuilder: (offsetY) => FilterDraggableThumbLabel( + sortFactor: sortFactor, + offsetY: offsetY, + ), + crumbTextBuilder: (offsetY) => const SizedBox(), + child: scrollView, + ); + }, + ); + }, + ); + }, ); } diff --git a/lib/widgets/navigation/nav_bar/floating.dart b/lib/widgets/navigation/nav_bar/floating.dart index f4df637e2..b13387dbc 100644 --- a/lib/widgets/navigation/nav_bar/floating.dart +++ b/lib/widgets/navigation/nav_bar/floating.dart @@ -1,17 +1,21 @@ import 'dart:async'; +import 'dart:math'; import 'package:aves/widgets/common/basic/draggable_scrollbar.dart'; import 'package:flutter/material.dart'; +import 'package:flutter/rendering.dart'; class FloatingNavBar extends StatefulWidget { final ScrollController? scrollController; final Stream events; + final double childHeight; final Widget child; const FloatingNavBar({ super.key, required this.scrollController, required this.events, + required this.childHeight, required this.child, }); @@ -90,8 +94,6 @@ class _FloatingNavBarState extends State with SingleTickerProvid } void _onScrollChange() { - if (_isDragging) return; - final scrollController = widget.scrollController; if (scrollController == null) return; @@ -99,13 +101,22 @@ class _FloatingNavBarState extends State with SingleTickerProvid _delta += offset - (_lastOffset ?? offset); _lastOffset = offset; + if (_isDragging) return; + + final after = scrollController.position.extentAfter; + final childHeight = widget.childHeight; + if (after < childHeight && scrollController.position.userScrollDirection == ScrollDirection.reverse) { + _controller.value = min(_controller.value, after / childHeight); + _delta = 0; + return; + } + if (_delta.abs() > _deltaThreshold) { if (_delta > 0) { _hide(); } else { _show(); } - _delta = 0; } } @@ -122,7 +133,13 @@ class _FloatingNavBarState extends State with SingleTickerProvid } } - void _show() => _controller.reverse(); + void _show() { + _controller.reverse(); + _delta = 0; + } - void _hide() => _controller.forward(); + void _hide() { + _controller.forward(); + _delta = 0; + } } diff --git a/lib/widgets/navigation/nav_bar/nav_bar.dart b/lib/widgets/navigation/nav_bar/nav_bar.dart index e3275a9d0..ea44104a0 100644 --- a/lib/widgets/navigation/nav_bar/nav_bar.dart +++ b/lib/widgets/navigation/nav_bar/nav_bar.dart @@ -6,6 +6,7 @@ import 'package:aves/model/source/collection_source.dart'; import 'package:aves/widgets/collection/collection_page.dart'; import 'package:aves/widgets/common/basic/draggable_scrollbar.dart'; import 'package:aves/widgets/common/extensions/build_context.dart'; +import 'package:aves/widgets/common/extensions/media_query.dart'; import 'package:aves/widgets/common/fx/blurred.dart'; import 'package:aves/widgets/filter_grids/albums_page.dart'; import 'package:aves/widgets/navigation/nav_bar/floating.dart'; @@ -79,6 +80,7 @@ class AppBottomNavBar extends StatelessWidget { child: FloatingNavBar( scrollController: PrimaryScrollController.of(context), events: events, + childHeight: height + context.select((mq) => mq.effectiveBottomPadding), child: SafeArea( child: child, ),