improved nav bar visibility
This commit is contained in:
parent
b0df94a4fa
commit
fecfa45a29
4 changed files with 98 additions and 58 deletions
|
@ -350,9 +350,14 @@ class _CollectionScrollViewState extends State<_CollectionScrollView> {
|
||||||
Widget _buildDraggableScrollView(ScrollView scrollView, CollectionLens collection) {
|
Widget _buildDraggableScrollView(ScrollView scrollView, CollectionLens collection) {
|
||||||
return ValueListenableBuilder<double>(
|
return ValueListenableBuilder<double>(
|
||||||
valueListenable: widget.appBarHeightNotifier,
|
valueListenable: widget.appBarHeightNotifier,
|
||||||
builder: (context, appBarHeight, child) => Selector<MediaQueryData, double>(
|
builder: (context, appBarHeight, child) {
|
||||||
|
return Selector<MediaQueryData, double>(
|
||||||
selector: (context, mq) => mq.effectiveBottomPadding,
|
selector: (context, mq) => mq.effectiveBottomPadding,
|
||||||
builder: (context, mqPaddingBottom, child) {
|
builder: (context, mqPaddingBottom, child) {
|
||||||
|
return Selector<Settings, bool>(
|
||||||
|
selector: (context, s) => s.showBottomNavigationBar,
|
||||||
|
builder: (context, showBottomNavigationBar, child) {
|
||||||
|
final navBarHeight = showBottomNavigationBar ? AppBottomNavBar.height : 0;
|
||||||
return Selector<SectionedListLayout<AvesEntry>, List<SectionLayout>>(
|
return Selector<SectionedListLayout<AvesEntry>, List<SectionLayout>>(
|
||||||
selector: (context, layout) => layout.sectionLayouts,
|
selector: (context, layout) => layout.sectionLayouts,
|
||||||
builder: (context, sectionLayouts, child) {
|
builder: (context, sectionLayouts, child) {
|
||||||
|
@ -368,7 +373,7 @@ class _CollectionScrollViewState extends State<_CollectionScrollView> {
|
||||||
padding: EdgeInsets.only(
|
padding: EdgeInsets.only(
|
||||||
// padding to keep scroll thumb between app bar above and nav bar below
|
// padding to keep scroll thumb between app bar above and nav bar below
|
||||||
top: appBarHeight,
|
top: appBarHeight,
|
||||||
bottom: mqPaddingBottom,
|
bottom: navBarHeight + mqPaddingBottom,
|
||||||
),
|
),
|
||||||
labelTextBuilder: (offsetY) => CollectionDraggableThumbLabel(
|
labelTextBuilder: (offsetY) => CollectionDraggableThumbLabel(
|
||||||
collection: collection,
|
collection: collection,
|
||||||
|
@ -380,7 +385,10 @@ class _CollectionScrollViewState extends State<_CollectionScrollView> {
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
),
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -512,9 +512,17 @@ class _FilterScrollView<T extends CollectionFilter> extends StatelessWidget {
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildDraggableScrollView(ScrollView scrollView) {
|
Widget _buildDraggableScrollView(ScrollView scrollView) {
|
||||||
|
return ValueListenableBuilder<double>(
|
||||||
|
valueListenable: appBarHeightNotifier,
|
||||||
|
builder: (context, appBarHeight, child) {
|
||||||
return Selector<MediaQueryData, double>(
|
return Selector<MediaQueryData, double>(
|
||||||
selector: (context, mq) => mq.effectiveBottomPadding,
|
selector: (context, mq) => mq.effectiveBottomPadding,
|
||||||
builder: (context, mqPaddingBottom, child) => DraggableScrollbar(
|
builder: (context, mqPaddingBottom, child) {
|
||||||
|
return Selector<Settings, bool>(
|
||||||
|
selector: (context, s) => s.showBottomNavigationBar,
|
||||||
|
builder: (context, showBottomNavigationBar, child) {
|
||||||
|
final navBarHeight = showBottomNavigationBar ? AppBottomNavBar.height : 0;
|
||||||
|
return DraggableScrollbar(
|
||||||
backgroundColor: Colors.white,
|
backgroundColor: Colors.white,
|
||||||
scrollThumbSize: Size(avesScrollThumbWidth, avesScrollThumbHeight),
|
scrollThumbSize: Size(avesScrollThumbWidth, avesScrollThumbHeight),
|
||||||
scrollThumbBuilder: avesScrollThumbBuilder(
|
scrollThumbBuilder: avesScrollThumbBuilder(
|
||||||
|
@ -524,8 +532,8 @@ class _FilterScrollView<T extends CollectionFilter> extends StatelessWidget {
|
||||||
controller: scrollController,
|
controller: scrollController,
|
||||||
padding: EdgeInsets.only(
|
padding: EdgeInsets.only(
|
||||||
// padding to keep scroll thumb between app bar above and nav bar below
|
// padding to keep scroll thumb between app bar above and nav bar below
|
||||||
top: appBarHeightNotifier.value,
|
top: appBarHeight,
|
||||||
bottom: mqPaddingBottom,
|
bottom: navBarHeight + mqPaddingBottom,
|
||||||
),
|
),
|
||||||
labelTextBuilder: (offsetY) => FilterDraggableThumbLabel<T>(
|
labelTextBuilder: (offsetY) => FilterDraggableThumbLabel<T>(
|
||||||
sortFactor: sortFactor,
|
sortFactor: sortFactor,
|
||||||
|
@ -533,7 +541,12 @@ class _FilterScrollView<T extends CollectionFilter> extends StatelessWidget {
|
||||||
),
|
),
|
||||||
crumbTextBuilder: (offsetY) => const SizedBox(),
|
crumbTextBuilder: (offsetY) => const SizedBox(),
|
||||||
child: scrollView,
|
child: scrollView,
|
||||||
),
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,17 +1,21 @@
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
import 'dart:math';
|
||||||
|
|
||||||
import 'package:aves/widgets/common/basic/draggable_scrollbar.dart';
|
import 'package:aves/widgets/common/basic/draggable_scrollbar.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter/rendering.dart';
|
||||||
|
|
||||||
class FloatingNavBar extends StatefulWidget {
|
class FloatingNavBar extends StatefulWidget {
|
||||||
final ScrollController? scrollController;
|
final ScrollController? scrollController;
|
||||||
final Stream<DraggableScrollBarEvent> events;
|
final Stream<DraggableScrollBarEvent> events;
|
||||||
|
final double childHeight;
|
||||||
final Widget child;
|
final Widget child;
|
||||||
|
|
||||||
const FloatingNavBar({
|
const FloatingNavBar({
|
||||||
super.key,
|
super.key,
|
||||||
required this.scrollController,
|
required this.scrollController,
|
||||||
required this.events,
|
required this.events,
|
||||||
|
required this.childHeight,
|
||||||
required this.child,
|
required this.child,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -90,8 +94,6 @@ class _FloatingNavBarState extends State<FloatingNavBar> with SingleTickerProvid
|
||||||
}
|
}
|
||||||
|
|
||||||
void _onScrollChange() {
|
void _onScrollChange() {
|
||||||
if (_isDragging) return;
|
|
||||||
|
|
||||||
final scrollController = widget.scrollController;
|
final scrollController = widget.scrollController;
|
||||||
if (scrollController == null) return;
|
if (scrollController == null) return;
|
||||||
|
|
||||||
|
@ -99,13 +101,22 @@ class _FloatingNavBarState extends State<FloatingNavBar> with SingleTickerProvid
|
||||||
_delta += offset - (_lastOffset ?? offset);
|
_delta += offset - (_lastOffset ?? 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.abs() > _deltaThreshold) {
|
||||||
if (_delta > 0) {
|
if (_delta > 0) {
|
||||||
_hide();
|
_hide();
|
||||||
} else {
|
} else {
|
||||||
_show();
|
_show();
|
||||||
}
|
}
|
||||||
_delta = 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -122,7 +133,13 @@ class _FloatingNavBarState extends State<FloatingNavBar> with SingleTickerProvid
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void _show() => _controller.reverse();
|
void _show() {
|
||||||
|
_controller.reverse();
|
||||||
|
_delta = 0;
|
||||||
|
}
|
||||||
|
|
||||||
void _hide() => _controller.forward();
|
void _hide() {
|
||||||
|
_controller.forward();
|
||||||
|
_delta = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,7 @@ import 'package:aves/model/source/collection_source.dart';
|
||||||
import 'package:aves/widgets/collection/collection_page.dart';
|
import 'package:aves/widgets/collection/collection_page.dart';
|
||||||
import 'package:aves/widgets/common/basic/draggable_scrollbar.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/build_context.dart';
|
||||||
|
import 'package:aves/widgets/common/extensions/media_query.dart';
|
||||||
import 'package:aves/widgets/common/fx/blurred.dart';
|
import 'package:aves/widgets/common/fx/blurred.dart';
|
||||||
import 'package:aves/widgets/filter_grids/albums_page.dart';
|
import 'package:aves/widgets/filter_grids/albums_page.dart';
|
||||||
import 'package:aves/widgets/navigation/nav_bar/floating.dart';
|
import 'package:aves/widgets/navigation/nav_bar/floating.dart';
|
||||||
|
@ -79,6 +80,7 @@ class AppBottomNavBar extends StatelessWidget {
|
||||||
child: FloatingNavBar(
|
child: FloatingNavBar(
|
||||||
scrollController: PrimaryScrollController.of(context),
|
scrollController: PrimaryScrollController.of(context),
|
||||||
events: events,
|
events: events,
|
||||||
|
childHeight: height + context.select<MediaQueryData, double>((mq) => mq.effectiveBottomPadding),
|
||||||
child: SafeArea(
|
child: SafeArea(
|
||||||
child: child,
|
child: child,
|
||||||
),
|
),
|
||||||
|
|
Loading…
Reference in a new issue