From 431dfc83263b395299523b0ea1e2eba69cd68002 Mon Sep 17 00:00:00 2001 From: fzyzcjy <5236035+fzyzcjy@users.noreply.github.com> Date: Tue, 9 May 2023 03:03:06 +0800 Subject: [PATCH] Tiny cleanup for Navigator code (without introducing dependency) (#125628) Close https://github.com/flutter/flutter/issues/125724 > The `navigator.dart` has ~10 repeats of things like: > > ```dart > final _RouteEntry? currentRouteEntry = _navigator!._history.cast<_RouteEntry?>().lastWhere( > (_RouteEntry? e) => e != null && _RouteEntry.isPresentPredicate(e), > orElse: () => null, > ); > ``` > > while it can be greatly simplified as: > > ```dart > final _RouteEntry? currentRouteEntry = _navigator!._history.lastWhereOrNull(_RouteEntry.isPresentPredicate); > ``` > > Thus, it seems that we can beautify the code a little bit. Same as https://github.com/flutter/flutter/pull/125099, but without external dependency For more detailed explanation why it does not introduce external dependency: https://github.com/flutter/flutter/pull/125099#discussion_r1174230502 --- .../flutter/lib/src/widgets/navigator.dart | 70 ++++++++----------- 1 file changed, 31 insertions(+), 39 deletions(-) diff --git a/packages/flutter/lib/src/widgets/navigator.dart b/packages/flutter/lib/src/widgets/navigator.dart index 23cdeaf9973..a176892d99d 100644 --- a/packages/flutter/lib/src/widgets/navigator.dart +++ b/packages/flutter/lib/src/widgets/navigator.dart @@ -464,10 +464,7 @@ abstract class Route { if (_navigator == null) { return false; } - final _RouteEntry? currentRouteEntry = _navigator!._history.cast<_RouteEntry?>().lastWhere( - (_RouteEntry? e) => e != null && _RouteEntry.isPresentPredicate(e), - orElse: () => null, - ); + final _RouteEntry? currentRouteEntry = _navigator!._lastRouteEntryWhereOrNull(_RouteEntry.isPresentPredicate); if (currentRouteEntry == null) { return false; } @@ -482,10 +479,7 @@ abstract class Route { if (_navigator == null) { return false; } - final _RouteEntry? currentRouteEntry = _navigator!._history.cast<_RouteEntry?>().firstWhere( - (_RouteEntry? e) => e != null && _RouteEntry.isPresentPredicate(e), - orElse: () => null, - ); + final _RouteEntry? currentRouteEntry = _navigator!._firstRouteEntryWhereOrNull(_RouteEntry.isPresentPredicate); if (currentRouteEntry == null) { return false; } @@ -522,10 +516,7 @@ abstract class Route { if (_navigator == null) { return false; } - return _navigator!._history.cast<_RouteEntry?>().firstWhere( - (_RouteEntry? e) => e != null && _RouteEntry.isRoutePredicate(this)(e), - orElse: () => null, - )?.isPresent ?? false; + return _navigator!._firstRouteEntryWhereOrNull(_RouteEntry.isRoutePredicate(this))?.isPresent ?? false; } } @@ -4049,9 +4040,7 @@ class NavigatorState extends State with TickerProviderStateMixin, Res // Announce route name changes. if (widget.reportsRouteUpdateToEngine) { - final _RouteEntry? lastEntry = _history.cast<_RouteEntry?>().lastWhere( - (_RouteEntry? e) => e != null && _RouteEntry.isPresentPredicate(e), orElse: () => null, - ); + final _RouteEntry? lastEntry = _lastRouteEntryWhereOrNull(_RouteEntry.isPresentPredicate); final String? routeName = lastEntry?.route.settings.name; if (routeName != null && routeName != _lastAnnouncedRouteName) { SystemNavigator.routeInformationUpdated(uri: Uri.parse(routeName)); @@ -4929,10 +4918,7 @@ class NavigatorState extends State with TickerProviderStateMixin, Res /// to define the route's `willPop` method. @optionalTypeArgs Future maybePop([ T? result ]) async { - final _RouteEntry? lastEntry = _history.cast<_RouteEntry?>().lastWhere( - (_RouteEntry? e) => e != null && _RouteEntry.isPresentPredicate(e), - orElse: () => null, - ); + final _RouteEntry? lastEntry = _lastRouteEntryWhereOrNull(_RouteEntry.isPresentPredicate); if (lastEntry == null) { return false; } @@ -4942,10 +4928,7 @@ class NavigatorState extends State with TickerProviderStateMixin, Res // Forget about this pop, we were disposed in the meantime. return true; } - final _RouteEntry? newLastEntry = _history.cast<_RouteEntry?>().lastWhere( - (_RouteEntry? e) => e != null && _RouteEntry.isPresentPredicate(e), - orElse: () => null, - ); + final _RouteEntry? newLastEntry = _lastRouteEntryWhereOrNull(_RouteEntry.isPresentPredicate); if (lastEntry != newLastEntry) { // Forget about this pop, something happened to our history in the meantime. return true; @@ -5029,19 +5012,13 @@ class NavigatorState extends State with TickerProviderStateMixin, Res /// ``` /// {@end-tool} void popUntil(RoutePredicate predicate) { - _RouteEntry? candidate = _history.cast<_RouteEntry?>().lastWhere( - (_RouteEntry? e) => e != null && _RouteEntry.isPresentPredicate(e), - orElse: () => null, - ); + _RouteEntry? candidate = _lastRouteEntryWhereOrNull(_RouteEntry.isPresentPredicate); while(candidate != null) { if (predicate(candidate.route)) { return; } pop(); - candidate = _history.cast<_RouteEntry?>().lastWhere( - (_RouteEntry? e) => e != null && _RouteEntry.isPresentPredicate(e), - orElse: () => null, - ); + candidate = _lastRouteEntryWhereOrNull(_RouteEntry.isPresentPredicate); } } @@ -5065,10 +5042,7 @@ class NavigatorState extends State with TickerProviderStateMixin, Res }()); if (wasCurrent) { _afterNavigation( - _history.cast<_RouteEntry?>().lastWhere( - (_RouteEntry? e) => e != null && _RouteEntry.isPresentPredicate(e), - orElse: () => null, - )?.route, + _lastRouteEntryWhereOrNull(_RouteEntry.isPresentPredicate)?.route, ); } } @@ -5142,10 +5116,7 @@ class NavigatorState extends State with TickerProviderStateMixin, Res @optionalTypeArgs Route? _getRouteById(String id) { - return _history.cast<_RouteEntry?>().firstWhere( - (_RouteEntry? entry) => entry!.restorationId == id, - orElse: () => null, - )?.route as Route?; + return _firstRouteEntryWhereOrNull((_RouteEntry entry) => entry.restorationId == id)?.route as Route?; } int get _userGesturesInProgress => _userGesturesInProgressCount; @@ -5233,6 +5204,27 @@ class NavigatorState extends State with TickerProviderStateMixin, Res _activePointers.toList().forEach(WidgetsBinding.instance.cancelPointer); } + /// Gets first route entry satisfying the predicate, or null if not found. + _RouteEntry? _firstRouteEntryWhereOrNull(_RouteEntryPredicate test) { + for (final _RouteEntry element in _history) { + if (test(element)) { + return element; + } + } + return null; + } + + /// Gets last route entry satisfying the predicate, or null if not found. + _RouteEntry? _lastRouteEntryWhereOrNull(_RouteEntryPredicate test) { + _RouteEntry? result; + for (final _RouteEntry element in _history) { + if (test(element)) { + result = element; + } + } + return result; + } + @override Widget build(BuildContext context) { assert(!_debugLocked);