mirror of
https://github.com/lichess-org/mobile.git
synced 2026-05-26 13:50:52 +00:00
206 lines
8.5 KiB
Diff
206 lines
8.5 KiB
Diff
diff --git a/packages/flutter/lib/src/cupertino/nav_bar.dart b/packages/flutter/lib/src/cupertino/nav_bar.dart
|
|
index 1495f55d2d..a3ef08bdb6 100644
|
|
--- a/packages/flutter/lib/src/cupertino/nav_bar.dart
|
|
+++ b/packages/flutter/lib/src/cupertino/nav_bar.dart
|
|
@@ -31,6 +31,10 @@ const double _kNavBarLargeTitleHeightExtension = 52.0;
|
|
/// from the normal navigation bar to a big title below the navigation bar.
|
|
const double _kNavBarShowLargeTitleThreshold = 10.0;
|
|
|
|
+/// Number of logical pixels scrolled during which the navigation bar's background
|
|
+/// fades in or out.
|
|
+const _kNavBarScrollUnderAnimationExtent = 10.0;
|
|
+
|
|
const double _kNavBarEdgePadding = 16.0;
|
|
|
|
const double _kNavBarBottomPadding = 8.0;
|
|
@@ -432,17 +436,81 @@ class CupertinoNavigationBar extends StatefulWidget implements ObstructingPrefer
|
|
class _CupertinoNavigationBarState extends State<CupertinoNavigationBar> {
|
|
late _NavigationBarStaticComponentsKeys keys;
|
|
|
|
+ ScrollNotificationObserverState? _scrollNotificationObserver;
|
|
+ double _scrollAnimationValue = 0.0;
|
|
+
|
|
+ @override
|
|
+ void didChangeDependencies() {
|
|
+ super.didChangeDependencies();
|
|
+ _scrollNotificationObserver?.removeListener(_handleScrollNotification);
|
|
+ _scrollNotificationObserver = ScrollNotificationObserver.maybeOf(context);
|
|
+ _scrollNotificationObserver?.addListener(_handleScrollNotification);
|
|
+ }
|
|
+
|
|
+ @override
|
|
+ void dispose() {
|
|
+ if (_scrollNotificationObserver != null) {
|
|
+ _scrollNotificationObserver!.removeListener(_handleScrollNotification);
|
|
+ _scrollNotificationObserver = null;
|
|
+ }
|
|
+ super.dispose();
|
|
+ }
|
|
+
|
|
@override
|
|
void initState() {
|
|
super.initState();
|
|
keys = _NavigationBarStaticComponentsKeys();
|
|
}
|
|
|
|
+ void _handleScrollNotification(ScrollNotification notification) {
|
|
+ if (notification is ScrollUpdateNotification && notification.depth == 0) {
|
|
+ final ScrollMetrics metrics = notification.metrics;
|
|
+ final oldScrollAnimationValue = _scrollAnimationValue;
|
|
+ double scrollExtent = 0.0;
|
|
+ switch (metrics.axisDirection) {
|
|
+ case AxisDirection.up:
|
|
+ // Scroll view is reversed
|
|
+ scrollExtent = metrics.extentAfter;
|
|
+ case AxisDirection.down:
|
|
+ scrollExtent = metrics.extentBefore;
|
|
+ case AxisDirection.right:
|
|
+ case AxisDirection.left:
|
|
+ // Scrolled under is only supported in the vertical axis, and should
|
|
+ // not be altered based on horizontal notifications of the same
|
|
+ // predicate since it could be a 2D scroller.
|
|
+ break;
|
|
+ }
|
|
+
|
|
+ if (scrollExtent >= 0 && scrollExtent < _kNavBarScrollUnderAnimationExtent) {
|
|
+ setState(() {
|
|
+ _scrollAnimationValue = clampDouble(scrollExtent / _kNavBarScrollUnderAnimationExtent, 0, 1);
|
|
+ });
|
|
+ } else if (scrollExtent > _kNavBarScrollUnderAnimationExtent && oldScrollAnimationValue != 1.0) {
|
|
+ setState(() {
|
|
+ _scrollAnimationValue = 1.0;
|
|
+ });
|
|
+ } else if (scrollExtent <= 0 && oldScrollAnimationValue != 0.0) {
|
|
+ setState(() {
|
|
+ _scrollAnimationValue = 0.0;
|
|
+ });
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
final Color backgroundColor =
|
|
CupertinoDynamicColor.maybeResolve(widget.backgroundColor, context) ?? CupertinoTheme.of(context).barBackgroundColor;
|
|
|
|
+ final Border? effectiveBorder = Border.lerp(
|
|
+ const Border(bottom: BorderSide(width: 0.0, color: Color(0x00000000))),
|
|
+ widget.border,
|
|
+ _scrollAnimationValue,
|
|
+ );
|
|
+
|
|
+ final initialBackgroundColor = CupertinoTheme.of(context).scaffoldBackgroundColor;
|
|
+ final Color effectiveBackgroundColor = Color.lerp(initialBackgroundColor, backgroundColor, _scrollAnimationValue)!;
|
|
+
|
|
final _NavigationBarStaticComponents components = _NavigationBarStaticComponents(
|
|
keys: keys,
|
|
route: ModalRoute.of(context),
|
|
@@ -458,8 +526,8 @@ class _CupertinoNavigationBarState extends State<CupertinoNavigationBar> {
|
|
);
|
|
|
|
final Widget navBar = _wrapWithBackground(
|
|
- border: widget.border,
|
|
- backgroundColor: backgroundColor,
|
|
+ border: effectiveBorder,
|
|
+ backgroundColor: effectiveBackgroundColor,
|
|
brightness: widget.brightness,
|
|
child: DefaultTextStyle(
|
|
style: CupertinoTheme.of(context).textTheme.textStyle,
|
|
@@ -488,11 +556,11 @@ class _CupertinoNavigationBarState extends State<CupertinoNavigationBar> {
|
|
transitionOnUserGestures: true,
|
|
child: _TransitionableNavigationBar(
|
|
componentsKeys: keys,
|
|
- backgroundColor: backgroundColor,
|
|
+ backgroundColor: effectiveBackgroundColor,
|
|
backButtonTextStyle: CupertinoTheme.of(context).textTheme.navActionTextStyle,
|
|
titleTextStyle: CupertinoTheme.of(context).textTheme.navTitleTextStyle,
|
|
largeTitleTextStyle: null,
|
|
- border: widget.border,
|
|
+ border: effectiveBorder,
|
|
hasUserMiddle: widget.middle != null,
|
|
largeExpanded: false,
|
|
child: navBar,
|
|
@@ -792,7 +860,13 @@ class _LargeTitleNavigationBarSliverDelegate
|
|
|
|
@override
|
|
Widget build(BuildContext context, double shrinkOffset, bool overlapsContent) {
|
|
- final bool showLargeTitle = shrinkOffset < maxExtent - minExtent - _kNavBarShowLargeTitleThreshold;
|
|
+ final double largeTitleThreshold = maxExtent - minExtent - _kNavBarShowLargeTitleThreshold;
|
|
+ final bool showLargeTitle = shrinkOffset < largeTitleThreshold;
|
|
+ final double shrinkAnimationValue = clampDouble(
|
|
+ (shrinkOffset - largeTitleThreshold - _kNavBarScrollUnderAnimationExtent) / _kNavBarScrollUnderAnimationExtent,
|
|
+ 0,
|
|
+ 1,
|
|
+ );
|
|
|
|
final _PersistentNavigationBar persistentNavigationBar =
|
|
_PersistentNavigationBar(
|
|
@@ -803,9 +877,21 @@ class _LargeTitleNavigationBarSliverDelegate
|
|
middleVisible: alwaysShowMiddle ? null : !showLargeTitle,
|
|
);
|
|
|
|
+ final Color effectiveBackgroundColor = Color.lerp(
|
|
+ CupertinoTheme.of(context).scaffoldBackgroundColor,
|
|
+ CupertinoDynamicColor.resolve(backgroundColor, context),
|
|
+ shrinkAnimationValue,
|
|
+ )!;
|
|
+
|
|
+ final Border? effectiveBorder = border == null ? null : Border.lerp(
|
|
+ const Border(bottom: BorderSide(width: 0.0, color: Color(0x00000000))),
|
|
+ border,
|
|
+ shrinkAnimationValue,
|
|
+ );
|
|
+
|
|
final Widget navBar = _wrapWithBackground(
|
|
- border: border,
|
|
- backgroundColor: CupertinoDynamicColor.resolve(backgroundColor, context),
|
|
+ border: effectiveBorder,
|
|
+ backgroundColor: effectiveBackgroundColor,
|
|
brightness: brightness,
|
|
child: DefaultTextStyle(
|
|
style: CupertinoTheme.of(context).textTheme.textStyle,
|
|
@@ -875,11 +961,11 @@ class _LargeTitleNavigationBarSliverDelegate
|
|
// needs to wrap the top level RenderBox rather than a RenderSliver.
|
|
child: _TransitionableNavigationBar(
|
|
componentsKeys: keys,
|
|
- backgroundColor: CupertinoDynamicColor.resolve(backgroundColor, context),
|
|
+ backgroundColor: effectiveBackgroundColor,
|
|
backButtonTextStyle: CupertinoTheme.of(context).textTheme.navActionTextStyle,
|
|
titleTextStyle: CupertinoTheme.of(context).textTheme.navTitleTextStyle,
|
|
largeTitleTextStyle: CupertinoTheme.of(context).textTheme.navLargeTitleTextStyle,
|
|
- border: border,
|
|
+ border: effectiveBorder,
|
|
hasUserMiddle: userMiddle != null && (alwaysShowMiddle || !showLargeTitle),
|
|
largeExpanded: showLargeTitle,
|
|
child: navBar,
|
|
@@ -1716,6 +1802,7 @@ class _NavigationBarTransition extends StatelessWidget {
|
|
AnimatedBuilder(
|
|
animation: animation,
|
|
builder: (BuildContext context, Widget? child) {
|
|
+
|
|
return _wrapWithBackground(
|
|
// Don't update the system status bar color mid-flight.
|
|
updateSystemUiOverlay: false,
|
|
diff --git a/packages/flutter/lib/src/cupertino/page_scaffold.dart b/packages/flutter/lib/src/cupertino/page_scaffold.dart
|
|
index 7eec24d908..4bc5fbc87a 100644
|
|
--- a/packages/flutter/lib/src/cupertino/page_scaffold.dart
|
|
+++ b/packages/flutter/lib/src/cupertino/page_scaffold.dart
|
|
@@ -165,7 +165,7 @@ class _CupertinoPageScaffoldState extends State<CupertinoPageScaffold> {
|
|
);
|
|
}
|
|
|
|
- return DecoratedBox(
|
|
+ final content = DecoratedBox(
|
|
decoration: BoxDecoration(
|
|
color: CupertinoDynamicColor.maybeResolve(widget.backgroundColor, context)
|
|
?? CupertinoTheme.of(context).scaffoldBackgroundColor,
|
|
@@ -198,6 +198,8 @@ class _CupertinoPageScaffoldState extends State<CupertinoPageScaffold> {
|
|
],
|
|
),
|
|
);
|
|
+
|
|
+ return ScrollNotificationObserver(child: content);
|
|
}
|
|
}
|
|
|