-
Notifications
You must be signed in to change notification settings - Fork 28.3k
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
hiding original hero after hero transition #37341
Conversation
cc @Piinks |
@@ -360,13 +368,13 @@ class _HeroState extends State<Hero> { | |||
'A Hero widget cannot be the descendant of another Hero widget.' | |||
); | |||
|
|||
final bool isHeroInFlight = _placeholderSize != null; | |||
final bool placeheld = _placeholderSize != null; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why change the name here? 'placeheld' seems a bit more ambiguous to understanding that the hero is currently flying.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This pr make it so after hero transition finishes, the hero widget in the original route will still be hidden. The placeheld (or isHeroInFlight previously) is controlling whether to hide the hero. After this change, we want to hide hero even if it is not in flight. I feel the name become confusing, and that is why i renamed it. I am open to any name suggestion tho
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe a better name would be: showPlaceholder?
|
||
manifest.fromHero.endFlight(); | ||
manifest.toHero.endFlight(); | ||
// There can only be one hero. The one on top should survive. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you elaborate further about what this means?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
one of the hero should be hidden after the flight, when AnimationStatus.completed toHero will be the one on top, if AnimationStatus.dismissed, it means it starts transition but got canceled, so the fromHero will be the one on top
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I will update the comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am not sure if anybody depends on those heroes becoming visible again, but for those people, this will be a nasty breaking change. Nasty, because their app will just compile fine and run without exceptions. It'll be hard for them to notice that something is broken. Again, I can't think of any reason for anybody to depend on the fact that the heroes in the route below become visible again, but if we want to do this as a breaking change, we should collect feedback by sending out a breaking change proposal and giving people some time to respond. The breaking change should also be clearly stated in the PR description.
We could also make this a non-breaking change by just having it as a config option on the hero and defaulting it to the current behavior.
if (!isUserGestureTransition || heroWidget.transitionOnUserGestures) { | ||
result[tag] = heroState; | ||
} else { | ||
// If transition is not allowed, we reset hero. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure what this comment means?
}); | ||
} | ||
|
||
void endFlight({ bool placeheld = false }) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add documentation what placeheld
means?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe the parameter should be named: keepPlaceholder.
setState(() { | ||
_placeholderSize = null; | ||
}); | ||
void reset() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can this get a more descriptive name? Maybe "ensurePlaceholderIsHidden"?
@@ -360,13 +368,13 @@ class _HeroState extends State<Hero> { | |||
'A Hero widget cannot be the descendant of another Hero widget.' | |||
); | |||
|
|||
final bool isHeroInFlight = _placeholderSize != null; | |||
final bool placeheld = _placeholderSize != null; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe a better name would be: showPlaceholder?
|
||
manifest.fromHero.endFlight(); | ||
manifest.toHero.endFlight(); | ||
// We want to hide the hero underneath the current page. If |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you have tests for both of these cases?
manifest.fromHero.endFlight(); | ||
manifest.toHero.endFlight(); | ||
// We want to hide the hero underneath the current page. If | ||
// [AnimationStatus.completed], toHero will be the one on top and we hide |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hide? fromHero is already hidden and we just keep it hidden, no?
// We want to hide the hero underneath the current page. If | ||
// [AnimationStatus.completed], toHero will be the one on top and we hide | ||
// fromHero. If [AnimationStatus.dismissed], the animation is triggered | ||
// but canceled before it finishes. In this case, we hide toHero instead. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same here?
if (manifest.fromHero != newManifest.toHero) { | ||
manifest.fromHero.endFlight(); | ||
// Aborted animation should be placeheld. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you have a test for this case?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also: why's the from hero placeheld?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think this will matter because the old heros are disposed, and it will not be testable because the elements are gone. I modify this just to be extra safe
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If it doesn't matter, I'd remove the comment. The comment makes it sound like that this is super-important.
@@ -630,8 +640,9 @@ class _HeroFlight { | |||
else | |||
_proxyAnimation.parent = newManifest.animation; | |||
|
|||
manifest.fromHero.endFlight(); | |||
manifest.toHero.endFlight(); | |||
// Aborted animations should be placeheld. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Tests for this code path?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Again, why do we hide them in this case?
I am struggle on whether to keep the original behavior. I think if we want to provide options, they will be either the fromHero is always displayed or the always hidden. The current behavior is just weird and ugly. |
}); | ||
} | ||
|
||
// The 'keepPlaceholder' flag dictates if the hero should keep the placeholder after |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// The 'keepPlaceholder' flag dictates if the hero should keep the placeholder after | |
// When `keepPlaceholder` is true, the placeholder will continue to be shown after the flight ends. |
if (manifest.fromHero != newManifest.toHero) { | ||
manifest.fromHero.endFlight(); | ||
// Aborted animation should be placeheld. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If it doesn't matter, I'd remove the comment. The comment makes it sound like that this is super-important.
You can collect feedback for this by sending out a proposal for this breaking change and we can add options if people depend on this. |
25d50d8
to
626a6b3
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
_placeholderSize = null; | ||
}); | ||
void ensurePlaceholderIsHidden() { | ||
setState(() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should probably be guarded by if (mounted)
and the if mounted should be removed from endFlight?
Is there any option or workaround to make the original hero always visible? |
@liuyingshan |
Description
If you transition for route 1 to route2, the hero in route1 is hidden during the transition and reappear after transition end. This is generally ok when route2 is not transparent, but looks weird when it is transparent.
after this pr it will hide the original hero
Related Issues
#10667
Tests
I added the following tests:
"Heroes animate should hide original hero"
Checklist
Before you create this PR confirm that it meets all requirements listed below by checking the relevant checkboxes (
[x]
). This will ensure a smooth and quick review process.///
).flutter analyze --flutter-repo
) does not report any problems on my PR.Breaking Change
Does your PR require Flutter developers to manually update their apps to accommodate your change?