Fix layout animations when adding and removing views at the same time on Android #16091
+84
−17
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Actual fix for #7959 that was abandoned because of some issues with that implementation.
This fixes some view hierarchy inconsistencies caused by layout delete animations. The fix is similar to what was done on iOS recently. To be able to do so properly we introduce "React" views in
ViewGroupManager
to allow the native view hierarchy to diverge from what React knows about.This also fixes another bug that is caused by animations being interrupted. To fix this we make sure to
clearAnimations
before starting a new one so thatonAnimationEnd
is called and we update the opacity to the final value there in case the animation didn't finish. Sadly Android seems to have really bad support for running multiple animations at the same time so just updating the value to the final value was the best fix for now.Caveats
This won't work if the parent uses
removeClippedSubviews
. In that case it doesn't useViewGroupManager
methods because it implements its own way of having a different native and react view hierarchies. Since we're moving away fromremoveClippedSubviews
(I think so haha), I didn't bother trying to make it work. This might be a bad idea since it will crash with some out of bounds errors and I'm not sure how we could detect that and show a useful warning. Another alternative would be to use the new React views api to reimplement subview clipping but I'd rather not mess with that code tbh :).Perf
This should have a negligible impact since we're only adding a single map lookup to view operations for views that don't diverge from their native view hierarchy. It might be worth trying to add a check to get rid of the additional mapping if we detect that both native and react children becomes the same again after diverging.
Test plan
Used this gist https://gist.github.com/janicduplessis/211d78c5408ab17dee7ad2e381648a48 to reproduce the bugs and made sure there was no longer any inconsistencies when spamming a bunch of add and remove views. Also made sure no views were leaked because of the extra mapping we keep in
mReactChildrenMap
.