Skip to content

[material_ui] Handle unknown swipe edges in predictive back transitions - #12502

Open
muhammadkamel wants to merge 5 commits into
flutter:mainfrom
muhammadkamel:fix/material-ui-predictive-back-swipe-edge
Open

muhammadkamel wants to merge 5 commits into
flutter:mainfrom
muhammadkamel:fix/material-ui-predictive-back-swipe-edge

Conversation

@muhammadkamel

Copy link
Copy Markdown
Contributor

Ports the Material side of flutter/flutter#185140 after the Material/Cupertino decoupling.

PredictiveBackPageTransitionsBuilder now treats unknown or button-triggered swipe edges as a no-direction fallback, matching Android BackEvent.EDGE_NONE. _ is used instead of SwipeEdge.none because that enum value is not in the Flutter SDK this package currently compiles against; it also keeps the switch exhaustive when the SDK gains new SwipeEdge values.

Adds coverage for right-edge swipes and for button-triggered back events (Offset.zero + progress: 0.0), which handleStartBackGesture already filters via isButtonEvent.

The RangeError in PredictiveBackEvent.fromMap for swipeEdge: 2 still lives in flutter/services and is fixed in flutter/flutter#191306. That crash cannot be fixed in this package.

Fixes flutter/flutter#186168

Pre-Review Checklist

  • I read the [Contributor Guide] and followed the process outlined there for submitting PRs.
  • I read the [AI contribution guidelines] and understand my responsibilities, or I am not using AI tools.
  • I read the [Tree Hygiene] page, which explains my responsibilities.
  • I read and followed the [relevant style guides] and ran [the auto-formatter].
  • I signed the [CLA].
  • The title of the PR starts with the name of the package surrounded by square brackets, e.g. [shared_preferences]
  • I [linked to at least one issue that this PR fixes] in the description above.
  • I followed [the version and CHANGELOG instructions], using [semantic versioning] and the [repository CHANGELOG style], or I have commented below to indicate which documented exception this PR falls under.
  • I updated/added any relevant documentation (doc comments with ///).
  • I added new tests to check the change I am making, or I have commented below to indicate which [test exemption] this PR falls under.
  • All existing and new tests are passing.

Treat unknown or button-triggered swipe edges as a no-direction fallback
so the switch stays exhaustive when the Flutter SDK adds SwipeEdge values.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request updates PredictiveBackPageTransitionsBuilder to treat unknown or button-triggered swipe edges as a no-direction fallback, and adds tests for right-edge swipes and button-triggered back events. The review feedback suggests simplifying the switch expression by removing the redundant SwipeEdge.left case, and using a more precise assertion in the tests to verify that the page shifts in the correct direction.

@github-actions github-actions Bot added triage-framework Should be looked at in framework triage p: material_ui labels Aug 18, 2026

@justinmc justinmc left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for porting your PR so quickly!

There's a slight change in process for material_ui and cupertino_ui regarding the changelog and version: you'll have to create a pending changelog yaml file. See https://github.com/flutter/packages/blob/main/packages/material_ui/pending_changelogs/template.yaml

Otherwise this looks good.

await tester.tap(find.text('push'));
await tester.pumpAndSettle();

if (defaultTargetPlatform != TargetPlatform.android) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this not be the skip and/or the variant argument of the test itself? For non Android, this test does setup and then no asserts, which reads a bit weird.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@muhammadkamel Maybe this was missed earlier, but you did not provide a reasoning for adding this return, over using a test variant or test skip?

await tester.tap(find.text('push'));
await tester.pumpAndSettle();

if (defaultTargetPlatform != TargetPlatform.android) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same remark here

@github-actions github-actions Bot added the triage-design Should be looked at in design triage label Aug 29, 2026
@muhammadkamel

Copy link
Copy Markdown
Contributor Author

Thanks for the review @justinmc and @navaronbracke! All comments have been addressed, please take another look.

@elliette

Copy link
Copy Markdown
Member

[from triage] friendly ping @justinmc @navaronbracke are you still reviewing this PR? Thanks!

@navaronbracke navaronbracke left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While the overall change SGTM, I did have an open question (from my last review), relating to the use of a return to skip part of the test.

I think it would be better if the tests could be split into an Android version (which uses the full test) and a non-Android version (which uses the part up to the returns in the test body)

await tester.tap(find.text('push'));
await tester.pumpAndSettle();

if (defaultTargetPlatform != TargetPlatform.android) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@muhammadkamel Maybe this was missed earlier, but you did not provide a reasoning for adding this return, over using a test variant or test skip?

Replace the early return on non-Android platforms with
TargetPlatformVariant.only(TargetPlatform.android), so the tests only
run where they make assertions.
@camle83it

Copy link
Copy Markdown

Dear @muhammadkamel @navaronbracke
Thank you for your work on this PR and for taking the time to address this issue.
If possible, could you please continue supporting this PR and help move it forward until the issue is fully resolved?

@elliette

Copy link
Copy Markdown
Member

cc @justinmc are you still reviewing this PR or would you like the ecosystem team to take over review? Thanks!

@muhammadkamel

Copy link
Copy Markdown
Contributor Author

Hi @elliette, I think @justinmc is on an extended vacation. Could we assign another reviewer to help get this PR merged soon?

@justinmc justinmc left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry I was traveling last week but back now. This looks good but I want to make sure adding a value to SwipeEdge is the right approach here, see my comment on that below.

Comment on lines +462 to +463
// `_` keeps the switch exhaustive if additional SwipeEdge values
// are added in the Flutter SDK.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@chunhtai I wonder what you think about this given that your RFC flutter/rfc#32 recommends against adding values to enums (see the framework side of this PR in flutter/flutter#185140). Should we migrate to a class-based SwipeEdge, or should we work with what we have for now?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this should stay an enum as it is closed by design (at most four directions)

@chunhtai chunhtai Nov 2, 2026 •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

unless Android start to support micro direction like bottom-left top-left. I doubt that will happen though, better not over-engineering now.

variant: TargetPlatformVariant.only(TargetPlatform.android),
);

testWidgets('button-triggered back does not start a predictive back animation', (

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: Maybe change this to say "system button triggered", since you are talking about Android's system back button, right? To disambiguate it with a Flutter button.

@justinmc justinmc left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok this LGTM then based on @chunhtai 's response. 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CICD Run CI/CD p: material_ui triage-design Should be looked at in design triage triage-framework Should be looked at in framework triage

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Android] PredictiveBackEvent.fromMap does not guard against invalid swipeEdge value

6 participants