Repository: flutter
Issue: BackButtonListener should be muted if route it's located in is not laying on top
Labels: c: new feature,framework,f: routes,c: proposal,P3,team-framework,triaged-framework

## Use case

I have a search route, in which I have a filtering, which can be resetted with back button press, for this I use BackButtonListener. However, from this search route, I also can go in some other route, a searched item. Now, if I press back button from this nested route, it will be catched and handled by the laying down the navigator stack listener, which can be workarounded by writing additional logic, but this doesn't feel right

## Proposal

Mute BackButtonListeners if they are located in the not on top route

## Code sample

<details>
<summary>Example code sample</summary>

```dart
import 'package:flutter/material.dart';

void main() {
  return runApp(App());
}

class App extends StatelessWidget {
  static GlobalKey<NavigatorState> navigatorKey = GlobalKey();

  @override
  Widget build(BuildContext context) {
    return MaterialApp.router(
      title: 'Flutter Demo',
      theme: ThemeData(primaryColor: Colors.white),
      routeInformationParser: AppRouteInformationParser(),
      routerDelegate: AppRouter.instance,
      debugShowCheckedModeBanner: false,
    );
  }
}

class HomeScreen extends StatefulWidget {
  HomeScreen({Key key}) : super(key: key);

  @override
  _HomeScreenState createState() => _HomeScreenState();
}

class _HomeScreenState extends State<HomeScreen> with RouteAware {
  final List<int> list = List.generate(1000, (index) => index);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: ElevatedButton(
          child: const Text('Go'),
          onPressed: () {
            showSearch(context: context, delegate: ImplementedSearchDelegate());
          },
        ),
      ),
    );
  }
}

class ImplementedSearchDelegate extends SearchDelegate {
  @override
  List<Widget> buildActions(BuildContext context) {
    return [];
  }
  
  @override
  Widget buildLeading(BuildContext context) {
    return Container();
  }
  
  @override
  Widget buildResults(BuildContext context) {
    return Container();
  }

  bool canPop = false; 
  @override
  Widget buildSuggestions(BuildContext context) {
    return BackButtonListener(
      onBackButtonPressed: () async {
        if (!canPop) {
          ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text('snack')));
          canPop = true;
          return true;
        }
        return false;
      },
      child: Center(
        child: ElevatedButton(
          child: const Text('Go'),
          onPressed: () {
            showAboutDialog(context: context);
          },
        ),
      ),
    );
  }
}

class AppRoutes {
  const AppRoutes._(this.location);
  final String location;

  static const home = AppRoutes._('/');
}

class AppRouteInformationParser extends RouteInformationParser<AppRoutes> {
  @override
  Future<AppRoutes> parseRouteInformation(RouteInformation routeInformation) async {
    return AppRoutes._(routeInformation.location);
  }

  @override
  RouteInformation restoreRouteInformation(AppRoutes configuration) {
    return RouteInformation(location: configuration.location);
  }
}

class AppRouter extends RouterDelegate<AppRoutes>
  with ChangeNotifier,
       PopNavigatorRouterDelegateMixin {

  AppRouter._();
  static final AppRouter instance = AppRouter._();

  AppRoutes _currentConfiguration = AppRoutes.home;

  @override
  AppRoutes get currentConfiguration => _currentConfiguration;

  @override
  Future<void> setNewRoutePath(AppRoutes configuration) async {
    _currentConfiguration = configuration;
    notifyListeners();
  }
         
  @override
  GlobalKey<NavigatorState> get navigatorKey => App.navigatorKey;

  @override
  Widget build(BuildContext context) {
    return Navigator(
      key: navigatorKey,
      pages: <Page<void>>[
        MaterialPage(
          key: ValueKey('home'),
          child: HomeScreen(),
        ),
      ],
      onPopPage: (route, result) {
        final bool success = route.didPop(result);
        if (success) {
          _currentConfiguration = AppRoutes.home;
        }
        return success;
      },
    );
  }
}
```
</details>

In the example above, currently the snackbar will be shown first, and only then you will be able to close the on top route.
Desired behavior is that this was the opposite.

CC @chunhtai