-
Notifications
You must be signed in to change notification settings - Fork 24.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
Fix view indices with Android LayoutAnimation (attempt 2) #19775
Fix view indices with Android LayoutAnimation (attempt 2) #19775
Conversation
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.
Nice work, sorry about the delay reviewing this!
@mdvacca Could you have a look to make sure this is fine? |
@lnikkila I tried to find reviewers for this pull request and wanted to ping them to take another look. However, based on the blame information for the files in this pull request I couldn't find any reviewers. This sometimes happens when the files in the pull request are new or don't exist on master anymore. Is this pull request still relevant? If yes could you please rebase? In case you know who has context on this code feel free to mention them in a comment (one person is fine). Thanks for reading and hope you will continue contributing to the project. |
@janicduplessis can you merge this in? |
@facebook-github-bot shipit |
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.
janicduplessis is landing this pull request. If you are a Facebook employee, you can view this diff on Phabricator.
I tried to merge this pull request into the Facebook internal repo but some checks failed. To unblock yourself please check the following: Does this pull request pass all open source tests on GitHub? If not please fix those. Does the code still apply cleanly on top of GitHub master? If not can please rebase. In all other cases this means some internal test failed, for example a part of a fb app won't work with this pull request. I've added the Import Failed label to this pull request so it is easy for someone at fb to find the pull request and check what failed. If you don't see anyone comment in a few days feel free to comment mentioning one of the core contributors to the project so they get a notification. |
Fixes issue #11828 that causes layout animations for removed views to remove some adjacent views as well. This happens because the animated views are still present in the ViewGroup, which throws off subsequent operations that rely on view indices having updated. This issue was addressed in #11962, which was closed in favour of a more reliable solution that addresses the issue globally since it’s difficult to account for animated views everywhere. @janicduplessis recommended[0] handling the issue through ViewManager. Since API 11, Android provides `ViewGroup#startViewTransition(View)` that can be used to keep child views visible even if they have been removed from the group. ViewGroup keeps an array of these views, which is only used for drawing. Methods such as `ViewGroup#getChildCount()` and `ViewGroup#getChildAt(int)` will ignore them. I believe relying on these framework methods within ViewManager is the most reliable way to solve this issue because it also works if callers ignore ViewManager and reach into the native view indices and counts directly. [0]: #11962 (review)
a1219b7
to
5245abe
Compare
@janicduplessis Rebased, if that helps. I noticed there was a three-way merge required for ReactViewGroup, so I went through the changes in master since and I don’t think there are any that would affect this. |
👍 Let's try landing it again @facebook-github-bot shipit |
@facebook-github-bot shipit |
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.
janicduplessis is landing this pull request. If you are a Facebook employee, you can view this diff on Phabricator.
This pull request was closed by @lnikkila in 1f88a71. Once this commit is added to a release, you will see the corresponding version tag below the description at 1f88a71. If the commit has a single |
This change is getting reverted on master, as we found it to be the cause of the following exception when used in our own products:
|
…9775) Summary: /cc janicduplessis mdvacca This addresses the same issue as facebook#18830 which was reverted since it didn’t handle `removeClippedSubviews` properly. When subview clipping is on, ReactViewGroup keeps track of its own children directly and accounts for the offset introduced by clipped views when calling ViewGroup methods that modify children. Instead of accounting for just clipped children (views with no parent), it should account for any children that aren’t in the ViewGroup which also includes children that are being transitioned. If you look at the ViewGroup source code, [it explicitly retains the view parent until the transition finishes](https://github.com/aosp-mirror/platform_frameworks_base/blob/oreo-release/core/java/android/view/ViewGroup.java#L5034-L5036) which caused the `getParent()` checks to pass, even though those views should be ignored. I added a new `isChildInViewGroup` method that handles both clipped and transitioning views to fix this. I reproduced the [earlier crash](facebook#18830 (comment)) by enabling clipping in [this test app](facebook#18830 (review)) and adding a “clear views” button that resets the state to an empty items array with an animation. - facebook#18830 [ANDROID] [BUGFIX] [LayoutAnimation] - Removal LayoutAnimations no longer remove adjacent views as well in certain cases. Pull Request resolved: facebook#19775 Differential Revision: D9105838 Pulled By: hramos fbshipit-source-id: 5ccb0957d1f46c36add960c0e4ef2a545cb03cbe
…9775) Summary: /cc janicduplessis mdvacca This addresses the same issue as facebook#18830 which was reverted since it didn’t handle `removeClippedSubviews` properly. When subview clipping is on, ReactViewGroup keeps track of its own children directly and accounts for the offset introduced by clipped views when calling ViewGroup methods that modify children. Instead of accounting for just clipped children (views with no parent), it should account for any children that aren’t in the ViewGroup which also includes children that are being transitioned. If you look at the ViewGroup source code, [it explicitly retains the view parent until the transition finishes](https://github.com/aosp-mirror/platform_frameworks_base/blob/oreo-release/core/java/android/view/ViewGroup.java#L5034-L5036) which caused the `getParent()` checks to pass, even though those views should be ignored. I added a new `isChildInViewGroup` method that handles both clipped and transitioning views to fix this. I reproduced the [earlier crash](facebook#18830 (comment)) by enabling clipping in [this test app](facebook#18830 (review)) and adding a “clear views” button that resets the state to an empty items array with an animation. - facebook#18830 [ANDROID] [BUGFIX] [LayoutAnimation] - Removal LayoutAnimations no longer remove adjacent views as well in certain cases. Pull Request resolved: facebook#19775 Differential Revision: D9105838 Pulled By: hramos fbshipit-source-id: 5ccb0957d1f46c36add960c0e4ef2a545cb03cbe
/cc @janicduplessis @mdvacca
This addresses the same issue as #18830 which was reverted since it didn’t handle
removeClippedSubviews
properly.When subview clipping is on, ReactViewGroup keeps track of its own children directly and accounts for the offset introduced by clipped views when calling ViewGroup methods that modify children.
Instead of accounting for just clipped children (views with no parent), it should account for any children that aren’t in the ViewGroup which also includes children that are being transitioned. If you look at the ViewGroup source code, it explicitly retains the view parent until the transition finishes which caused the
getParent()
checks to pass, even though those views should be ignored. I added a newisChildInViewGroup
method that handles both clipped and transitioning views to fix this.Test Plan
I reproduced the earlier crash by enabling clipping in this test app and adding a “clear views” button that resets the state to an empty items array with an animation.
Related PRs
Release Notes
[ANDROID] [BUGFIX] [LayoutAnimation] - Removal LayoutAnimations no longer remove adjacent views as well in certain cases.