Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PopScope can not work when I drag down ModalSheetRoute in Flutter 3.24 #233

Closed
Tommy-Wang0602 opened this issue Aug 28, 2024 · 4 comments
Closed
Assignees
Labels
bug Something isn't working P1
Milestone

Comments

@Tommy-Wang0602
Copy link

hi ~ @fujidaiti
I notice tutorial imperative_modal_sheet PopScopecan not work when I drag down ModalSheetRoute,expect will show dialog but doesn't

SDK version:
Flutter 3.24.0 • channel stable • https://github.com/flutter/flutter.git
Framework • revision 80c2e84975 (4 weeks ago) • 2024-07-30 23:06:49 +0700
Engine • revision b8800d88be
Tools • Dart 3.5.0 • DevTools 2.37.2

video:

2024-08-28.4.41.32.mov
  runApp(const _ImperativeModalSheetExample());
}

class _ImperativeModalSheetExample extends StatelessWidget {
  const _ImperativeModalSheetExample();

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      home: _ExampleHome(),
    );
  }
}

class _ExampleHome extends StatelessWidget {
  const _ExampleHome();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: ElevatedButton(
          onPressed: () => _showModalSheet(context),
          child: const Text('Show Modal Sheet'),
        ),
      ),
    );
  }
}

void _showModalSheet(BuildContext context) {
  // Use ModalSheetRoute to show a modal sheet with imperative Navigator API.
  // It works with any *Sheet provided by this package!
  final modalRoute = ModalSheetRoute(
    // Enable the swipe-to-dismiss behavior.
    swipeDismissible: true,
    builder: (context) => const _ExampleSheet(),
  );

  Navigator.push(context, modalRoute);
}

class _ExampleSheet extends StatelessWidget {
  const _ExampleSheet();

  @override
  Widget build(BuildContext context) {
    // You can use PopScope to handle the swipe-to-dismiss gestures, as well as
    // the system back gestures and tapping on the barrier, all in one place.
    return PopScope(
      canPop: false,
      onPopInvoked: (didPop) async {
        if (!didPop) {
          final shouldPop = await showConfirmationDialog(context);
          if (shouldPop == true && context.mounted) {
            Navigator.pop(context);
          }
        }
      },
      child: DraggableSheet(
        minExtent: const Extent.proportional(0.5),
        child: Card(
          color: Theme.of(context).colorScheme.secondaryContainer,
          margin: EdgeInsets.zero,
          shape: RoundedRectangleBorder(
            borderRadius: BorderRadius.circular(20),
          ),
          child: const SizedBox(
            height: 700,
            width: double.infinity,
          ),
        ),
      ),
    );
  }

  Future<bool?> showConfirmationDialog(BuildContext context) {
    return showDialog<bool>(
      context: context,
      builder: (context) {
        return AlertDialog(
          title: const Text('Are you sure?'),
          actions: [
            TextButton(
              onPressed: () => Navigator.pop(context, true),
              child: const Text('Yes'),
            ),
            TextButton(
              onPressed: () => Navigator.pop(context),
              child: const Text('No'),
            ),
          ],
        );
      },
    );
  }
}
@fujidaiti
Copy link
Owner

Hi @Tommy-Wang0602,

TL;DR

There are 2 options to work around this issue:

  1. Downgrade the Flutter SDK version to 3.22 or lower, or
  2. Fork the repo and replace this line with route.onPopInvokedWithResult(didPop, null);.

I'm planning to work on a solution soon...

Details

  1. The modal route uses the Route.onPopInvoked method to invoke the PopScope.onPopInvoked callback when the user swipes the sheet down to dismiss the modal.
  2. Flutter 3.24 has introduced a breaking change related to the PopScope widget, and PopScope.onPopInvoked is now deprecated.
  3. Accordingly, Route.onPopInvoked is also deprecated, and it no longer calls the PopScope.onPopInvoked callback (this is the reason why PopScope doesn't work with modals in the latest SDK).

As far as I know, the only solution is to replace Route.onPopInvoked with Route.onPopInvokedWithResult, which was newly added in Flutter 3.24. However, this solution forces package users to use the latest Flutter version, which is, of course, not ideal.

@fujidaiti fujidaiti added bug Something isn't working P1 labels Aug 28, 2024
@fujidaiti fujidaiti added this to the stable milestone Aug 28, 2024
@fujidaiti fujidaiti self-assigned this Aug 28, 2024
@fujidaiti fujidaiti changed the title PopScope can not work when I drag down ModalSheetRoute PopScope can not work when I drag down ModalSheetRoute in Flutter 3.24 Aug 29, 2024
@Tommy-Wang0602
Copy link
Author

@fujidaiti
Thank you for your response. May I also ask when approximately the next version will be released? Will this bug be resolved in the upcoming version?

@fujidaiti
Copy link
Owner

By this weekend, hopefully...

fujidaiti added a commit that referenced this issue Aug 31, 2024
…ersions in CI (#235)

## Related issues (optional)

Closes #229.

## Description

The workflow file was updated to run unit tests and static analysis for
both the lowest and highest supported Flutter SDK versions. This
approach helps detect potential compatibility issues across the entire
supported SDK range. For example, issue #144 stemmed from accidentally
using newly added APIs in Flutter 3.22 that don't exist in lower
versions, while issue #233 arose due to a breaking change introduced in
Flutter 3.24.


## Summary (check all that apply)

- [ ] Modified / added code
- [ ] Modified / added tests
- [ ] Modified / added examples
- [x] Modified / added others (pubspec.yaml, workflows, etc...)
- [ ] Updated README
- [ ] Contains breaking changes
  - [ ] Created / updated migration guide
- [ ] Incremented version number
  - [ ] Updated CHANGELOG
@fujidaiti fujidaiti mentioned this issue Aug 31, 2024
9 tasks
fujidaiti added a commit that referenced this issue Aug 31, 2024
## Description

Added regression tests for #233 and pinned Flutter version to v3.22.3
for development and CI. This downgrade was necessary as tests fail with
Flutter 3.24+ due to a [breaking
change](https://docs.flutter.dev/release/breaking-changes/popscope-with-result),
which caused that issue.

The fix for #233 is not included here as it requires Flutter 3.24+,
while the main branch will use v3.22.3 post-merge. To accommodate this
version disparity, the fix will be implemented in a separate branch,
providing distinct solutions for users of Flutter 3.24+ and 3.22.3 or
earlier.

## Summary (check all that apply)

- [ ] Modified / added code
- [x] Modified / added tests
- [ ] Modified / added examples
- [x] Modified / added others (pubspec.yaml, workflows, etc...)
- [ ] Updated README
- [ ] Contains breaking changes
  - [ ] Created / updated migration guide
- [ ] Incremented version number
  - [ ] Updated CHANGELOG
fujidaiti added a commit that referenced this issue Aug 31, 2024
## Related issues (optional)

Fixes #233.

## Description

This PR migrates from `Route.onPopInvoked` to
`Route.onPopInvokedWithResult` to address the issue. Here's a detailed
explanation of this change (quoted from the README):

> This package previously used the `Route.onPopInvoked` method to invoke
> `PopScope.onPopInvoked` callbacks when users performed a
> swipe-to-dismiss gesture. However, these methods were deprecated in
> Flutter 3.24.0 as part of a [breaking
> change](https://docs.flutter.dev/release/breaking-changes/popscope-with-result)
> related to the `PopScope` widget. The problem is that
> `ModalRoute.onPopInvoked`, which was an override of `Route.onPopInvoked`
> and where `PopScope.onPopInvoked` callbacks were actually invoked, was
> removed. As a result, the `PopScope.onPopInvoked` callback is no longer
> invoked in Flutter 3.24+. These changes led to issues such as
> [#233](#233).
> 
> The only possible solution was to replace `Route.onPopInvoked` with
> `Route.onPopInvokedWithResult`, which was introduced in Flutter 3.24.0.
> However, migrating to the new API would require increasing the lower
> bound of the SDK constraint to 3.24.0. For those using an SDK version
> lower than 3.24, this change would be a significant breaking change.
> Ultimately, we decided to publish different versions for different SDK
> constraints to maintain backward compatibility.

## Summary (check all that apply)

- [x] Modified / added code
- [ ] Modified / added tests
- [x] Modified / added examples
- [x] Modified / added others (pubspec.yaml, workflows, etc...)
- [x] Updated README
- [ ] Contains breaking changes
  - [ ] Created / updated migration guide
- [x] Incremented version number
  - [x] Updated CHANGELOG
@fujidaiti
Copy link
Owner

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working P1
Projects
None yet
Development

No branches or pull requests

2 participants