diff --git a/lib/components/navigation_bar.dart b/lib/components/navigation_bar.dart index 8f99760..3f65a5a 100644 --- a/lib/components/navigation_bar.dart +++ b/lib/components/navigation_bar.dart @@ -30,6 +30,7 @@ class NaviPane extends StatefulWidget { this.initialPage = 0, this.onPageChange, required this.observer, + required this.navigatorKey, super.key}); final List paneItems; @@ -44,6 +45,8 @@ class NaviPane extends StatefulWidget { final NaviObserver observer; + final GlobalKey navigatorKey; + @override State createState() => _NaviPaneState(); } @@ -60,6 +63,8 @@ class _NaviPaneState extends State widget.onPageChange?.call(value); } + void Function()? mainViewUpdateHandler; + late AnimationController controller; static const _kBottomBarHeight = 58.0; @@ -77,6 +82,16 @@ class _NaviPaneState extends State onRebuild(context); } + void updatePage(int index) { + if(widget.observer.routes.length > 1) { + widget.navigatorKey.currentState!.popUntil((route) => route.isFirst); + } + setState(() { + currentPage = index; + }); + mainViewUpdateHandler?.call(); + } + @override void initState() { controller = AnimationController( @@ -86,13 +101,11 @@ class _NaviPaneState extends State vsync: this, ); widget.observer.addListener(onNavigatorStateChange); - StateController.put(NaviPaddingWidgetController()); super.initState(); } @override void dispose() { - StateController.remove(); controller.dispose(); widget.observer.removeListener(onNavigatorStateChange); super.dispose(); @@ -101,9 +114,6 @@ class _NaviPaneState extends State double targetFormContext(BuildContext context) { var width = MediaQuery.of(context).size.width; double target = 0; - if (widget.observer.pageCount > 1) { - target = 1; - } if (width > changePoint) { target = 2; } @@ -125,19 +135,7 @@ class _NaviPaneState extends State controller.stop(); } } - if (target == 1) { - StateController.find() - .setWithPadding(true, true, true); - controller.value = target; - } else if (controller.value == 1 && target == 0) { - StateController.findOrNull() - ?.setWithPadding(false, false, false); - controller.value = target; - } else { - StateController.findOrNull() - ?.setWithPadding(false, false, false); - controller.animateTo(target); - } + controller.animateTo(target); animationTarget = target; } } @@ -160,40 +158,17 @@ class _NaviPaneState extends State final value = controller.value; return Stack( children: [ - if (value <= 1) - Positioned( - left: 0, - right: 0, - bottom: bottomBarHeight * (0 - value), - child: buildBottom(), - ), - if (value <= 1) - Positioned( - left: 0, - right: 0, - top: _kTopBarHeight * (0 - value) + - MediaQuery.of(context).padding.top * (1 - value), - child: buildTop(), - ), Positioned( left: _kFoldedSideBarWidth * ((value - 2.0).clamp(-1.0, 0.0)), top: 0, bottom: 0, child: buildLeft(), ), - Positioned( - top: _kTopBarHeight * ((1 - value).clamp(0, 1)) + - MediaQuery.of(context).padding.top * (value == 0 ? 1 : 0), + Positioned.fill( left: _kFoldedSideBarWidth * ((value - 1).clamp(0, 1)) + (_kSideBarWidth - _kFoldedSideBarWidth) * ((value - 2).clamp(0, 1)), - right: 0, - bottom: bottomBarHeight * ((1 - value).clamp(0, 1)), - child: MediaQuery.removePadding( - removeTop: value == 0, - context: context, - child: Material(child: widget.pageBuilder(currentPage)), - ), + child: buildMainView(), ), ], ); @@ -202,6 +177,24 @@ class _NaviPaneState extends State ); } + Widget buildMainView() { + return Navigator( + observers: [widget.observer], + key: widget.navigatorKey, + onGenerateRoute: (settings) => AppPageRoute( + preventRebuild: false, + isRootRoute: true, + builder: (context) { + return _NaviMainView(state: this); + }, + ), + ); + } + + Widget buildMainViewContent() { + return widget.pageBuilder(currentPage); + } + Widget buildTop() { return Material( child: Container( @@ -244,22 +237,25 @@ class _NaviPaneState extends State ), ), child: Padding( - padding: - EdgeInsets.only(bottom: MediaQuery.of(context).padding.bottom), + padding: EdgeInsets.only( + bottom: MediaQuery.of(context).padding.bottom, + ), child: Row( children: List.generate( - widget.paneItems.length, - (index) => Expanded( - child: _SingleBottomNaviWidget( - enabled: currentPage == index, - entry: widget.paneItems[index], - onTap: () { - setState(() { - currentPage = index; - }); - }, - key: ValueKey(index), - ))), + widget.paneItems.length, + (index) { + return Expanded( + child: _SingleBottomNaviWidget( + enabled: currentPage == index, + entry: widget.paneItems[index], + onTap: () { + updatePage(index); + }, + key: ValueKey(index), + ), + ); + }, + ), ), ), ), @@ -300,9 +296,7 @@ class _NaviPaneState extends State entry: widget.paneItems[index], showTitle: value == 3, onTap: () { - setState(() { - currentPage = index; - }); + updatePage(index); }, key: ValueKey(index), ), @@ -654,54 +648,44 @@ class _NaviPopScope extends StatelessWidget { } } -class NaviPaddingWidgetController extends StateController { - NaviPaddingWidgetController(); +class _NaviMainView extends StatefulWidget { + const _NaviMainView({required this.state}); - bool _withPadding = false; + final _NaviPaneState state; - bool _withTopBarPadding = false; - - bool _withBottomBarPadding = false; - - void setWithPadding( - bool withPadding, bool withAppbarPadding, bool withBottomBarPadding) { - _withPadding = withPadding; - _withTopBarPadding = withAppbarPadding; - _withBottomBarPadding = withBottomBarPadding; - update(); - } + @override + State<_NaviMainView> createState() => _NaviMainViewState(); } -class NaviPaddingWidget extends StatelessWidget { - const NaviPaddingWidget({super.key, required this.child}); +class _NaviMainViewState extends State<_NaviMainView> { + _NaviPaneState get state => widget.state; - final Widget child; + @override + void initState() { + state.mainViewUpdateHandler = () { + setState(() {}); + }; + super.initState(); + } @override Widget build(BuildContext context) { - return StateBuilder( - builder: (controller) { - return Padding( - padding: controller._withPadding - ? EdgeInsets.only( - top: context.padding.top + - (controller._withTopBarPadding - ? _NaviPaneState._kTopBarHeight - : 0), - bottom: context.padding.bottom + - (controller._withBottomBarPadding - ? _NaviPaneState._kBottomBarHeight - : 0), - ) - : EdgeInsets.zero, + var shouldShowAppBar = state.controller.value < 2; + return Column( + children: [ + if (shouldShowAppBar) state.buildTop().paddingTop(context.padding.top), + Expanded( child: MediaQuery.removePadding( - removeTop: controller._withPadding, - removeBottom: controller._withPadding, context: context, - child: child, + removeTop: shouldShowAppBar, + child: AnimatedSwitcher( + duration: _fastAnimationDuration, + child: state.buildMainViewContent(), + ), ), - ); - }, + ), + if (shouldShowAppBar) state.buildBottom().paddingBottom(context.padding.bottom), + ], ); } } diff --git a/lib/foundation/app_page_route.dart b/lib/foundation/app_page_route.dart index bab0f24..39d3bd6 100644 --- a/lib/foundation/app_page_route.dart +++ b/lib/foundation/app_page_route.dart @@ -2,7 +2,6 @@ import 'dart:math'; import 'dart:ui'; import 'package:flutter/gestures.dart'; import 'package:flutter/material.dart'; -import 'package:venera/components/components.dart'; const double _kBackGestureWidth = 20.0; const int _kMaxDroppedSwipePageForwardAnimationTime = 800; @@ -36,11 +35,7 @@ class AppPageRoute extends PageRoute with _AppRouteTransitionMixin{ @override Widget buildContent(BuildContext context) { var widget = builder(context); - if(widget is NaviPaddingWidget) { - label = widget.child.runtimeType.toString(); - } else { - label = widget.runtimeType.toString(); - } + label = widget.runtimeType.toString(); return widget; } diff --git a/lib/pages/main_page.dart b/lib/pages/main_page.dart index 37679b1..e074cad 100644 --- a/lib/pages/main_page.dart +++ b/lib/pages/main_page.dart @@ -6,7 +6,6 @@ import 'package:venera/utils/translations.dart'; import '../components/components.dart'; import '../foundation/app.dart'; -import '../foundation/app_page_route.dart'; import 'explore_page.dart'; import 'favorites/favorites_page.dart'; import 'home_page.dart'; @@ -56,6 +55,7 @@ class _MainPageState extends State { Widget build(BuildContext context) { return NaviPane( observer: _observer, + navigatorKey: _navigatorKey!, paneItems: [ PaneItemEntry( label: 'Home'.tl, @@ -96,32 +96,7 @@ class _MainPageState extends State { ) ], pageBuilder: (index) { - return Navigator( - observers: [_observer], - key: _navigatorKey, - onGenerateRoute: (settings) => AppPageRoute( - preventRebuild: false, - isRootRoute: true, - builder: (context) { - return NaviPaddingWidget(child: _pages[index]); - }, - ), - ); - }, - onPageChange: (index) { - setState(() { - this.index = index; - }); - _navigatorKey!.currentState?.pushAndRemoveUntil( - AppPageRoute( - preventRebuild: false, - isRootRoute: true, - builder: (context) { - return NaviPaddingWidget(child: _pages[index]); - }, - ), - (route) => false, - ); + return _pages[index]; }, ); }