improve ui

This commit is contained in:
nyne
2024-10-26 21:28:12 +08:00
parent 96bf3688d0
commit 9375263790
3 changed files with 84 additions and 130 deletions

View File

@@ -30,6 +30,7 @@ class NaviPane extends StatefulWidget {
this.initialPage = 0,
this.onPageChange,
required this.observer,
required this.navigatorKey,
super.key});
final List<PaneItemEntry> paneItems;
@@ -44,6 +45,8 @@ class NaviPane extends StatefulWidget {
final NaviObserver observer;
final GlobalKey<NavigatorState> navigatorKey;
@override
State<NaviPane> createState() => _NaviPaneState();
}
@@ -60,6 +63,8 @@ class _NaviPaneState extends State<NaviPane>
widget.onPageChange?.call(value);
}
void Function()? mainViewUpdateHandler;
late AnimationController controller;
static const _kBottomBarHeight = 58.0;
@@ -77,6 +82,16 @@ class _NaviPaneState extends State<NaviPane>
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<NaviPane>
vsync: this,
);
widget.observer.addListener(onNavigatorStateChange);
StateController.put(NaviPaddingWidgetController());
super.initState();
}
@override
void dispose() {
StateController.remove<NaviPaddingWidgetController>();
controller.dispose();
widget.observer.removeListener(onNavigatorStateChange);
super.dispose();
@@ -101,9 +114,6 @@ class _NaviPaneState extends State<NaviPane>
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<NaviPane>
controller.stop();
}
}
if (target == 1) {
StateController.find<NaviPaddingWidgetController>()
.setWithPadding(true, true, true);
controller.value = target;
} else if (controller.value == 1 && target == 0) {
StateController.findOrNull<NaviPaddingWidgetController>()
?.setWithPadding(false, false, false);
controller.value = target;
} else {
StateController.findOrNull<NaviPaddingWidgetController>()
?.setWithPadding(false, false, false);
controller.animateTo(target);
}
controller.animateTo(target);
animationTarget = target;
}
}
@@ -160,40 +158,17 @@ class _NaviPaneState extends State<NaviPane>
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<NaviPane>
);
}
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<NaviPane>
),
),
child: Padding(
padding:
EdgeInsets.only(bottom: MediaQuery.of(context).padding.bottom),
padding: EdgeInsets.only(
bottom: MediaQuery.of(context).padding.bottom,
),
child: Row(
children: List<Widget>.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<NaviPane>
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<NaviPaddingWidgetController>(
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),
],
);
}
}

View File

@@ -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<T> extends PageRoute<T> 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;
}

View File

@@ -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<MainPage> {
Widget build(BuildContext context) {
return NaviPane(
observer: _observer,
navigatorKey: _navigatorKey!,
paneItems: [
PaneItemEntry(
label: 'Home'.tl,
@@ -96,32 +96,7 @@ class _MainPageState extends State<MainPage> {
)
],
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];
},
);
}