mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
Track animations and flush them
Summary: Changelog: [Internal] Track delete animations and when `manageChildren` is called on a certain view tag, finish all pending deletion animations before manipulating children Reviewed By: JoshuaGross Differential Revision: D20319824 fbshipit-source-id: b594d0e6e9b6fecc5eca2938f284be631494e55c
This commit is contained in:
committed by
Facebook Github Bot
parent
d3b93f7578
commit
dedf9372ca
+3
@@ -363,6 +363,8 @@ public class NativeViewHierarchyManager {
|
||||
@Nullable int[] tagsToDelete) {
|
||||
UiThreadUtil.assertOnUiThread();
|
||||
|
||||
mLayoutAnimator.cancelAnimationsForViewTag(tag);
|
||||
|
||||
final ViewGroup viewToManage = (ViewGroup) mTagsToViews.get(tag);
|
||||
final ViewGroupManager viewManager = (ViewGroupManager) resolveViewManager(tag);
|
||||
if (viewToManage == null) {
|
||||
@@ -445,6 +447,7 @@ public class NativeViewHierarchyManager {
|
||||
|
||||
if (mLayoutAnimationEnabled && mLayoutAnimator.shouldAnimateLayout(viewToDestroy)) {
|
||||
mLayoutAnimator.deleteView(
|
||||
tag,
|
||||
viewToDestroy,
|
||||
new LayoutAnimationListener() {
|
||||
@Override
|
||||
|
||||
+40
-1
@@ -17,6 +17,7 @@ import androidx.annotation.Nullable;
|
||||
import com.facebook.react.bridge.Callback;
|
||||
import com.facebook.react.bridge.ReadableMap;
|
||||
import com.facebook.react.bridge.UiThreadUtil;
|
||||
import java.util.ArrayList;
|
||||
import javax.annotation.concurrent.NotThreadSafe;
|
||||
|
||||
/**
|
||||
@@ -31,6 +32,8 @@ public class LayoutAnimationController {
|
||||
private final AbstractLayoutAnimation mLayoutUpdateAnimation = new LayoutUpdateAnimation();
|
||||
private final AbstractLayoutAnimation mLayoutDeleteAnimation = new LayoutDeleteAnimation();
|
||||
private final SparseArray<LayoutHandlingAnimation> mLayoutHandlers = new SparseArray<>(0);
|
||||
private final SparseArray<ArrayList<Animation>> mDeleteAnimationsByParentTag =
|
||||
new SparseArray<>();
|
||||
|
||||
private boolean mShouldAnimateLayout;
|
||||
private long mMaxAnimationDuration = -1;
|
||||
@@ -113,6 +116,7 @@ public class LayoutAnimationController {
|
||||
|
||||
// Update an ongoing animation if possible, otherwise the layout update would be ignored as
|
||||
// the existing animation would still animate to the old layout.
|
||||
// Note the view is already inserted into the view hierarchy.
|
||||
LayoutHandlingAnimation existingAnimation = mLayoutHandlers.get(reactTag);
|
||||
if (existingAnimation != null) {
|
||||
existingAnimation.onLayoutUpdate(x, y, width, height);
|
||||
@@ -164,11 +168,14 @@ public class LayoutAnimationController {
|
||||
* Animate a view deletion using the layout animation configuration supplied during
|
||||
* initialization.
|
||||
*
|
||||
* @param parentReactTag tag of parent view of @param view. used to associate animation with for
|
||||
* canceling
|
||||
* @param view The view to animate.
|
||||
* @param listener Called once the animation is finished, should be used to completely remove the
|
||||
* view.
|
||||
*/
|
||||
public void deleteView(final View view, final LayoutAnimationListener listener) {
|
||||
public void deleteView(
|
||||
final int parentReactTag, final View view, final LayoutAnimationListener listener) {
|
||||
UiThreadUtil.assertOnUiThread();
|
||||
|
||||
Animation animation =
|
||||
@@ -188,6 +195,10 @@ public class LayoutAnimationController {
|
||||
|
||||
@Override
|
||||
public void onAnimationEnd(Animation anim) {
|
||||
ArrayList<Animation> animations = mDeleteAnimationsByParentTag.get(parentReactTag);
|
||||
if (animations != null) {
|
||||
animations.remove(anim);
|
||||
}
|
||||
listener.onAnimationEnd();
|
||||
}
|
||||
});
|
||||
@@ -198,7 +209,16 @@ public class LayoutAnimationController {
|
||||
mMaxAnimationDuration = animationDuration;
|
||||
}
|
||||
|
||||
// Update our tracking list of delete animations
|
||||
ArrayList<Animation> deleteAnimations = mDeleteAnimationsByParentTag.get(parentReactTag);
|
||||
if (deleteAnimations == null) {
|
||||
deleteAnimations = new ArrayList<>();
|
||||
mDeleteAnimationsByParentTag.put(parentReactTag, deleteAnimations);
|
||||
}
|
||||
deleteAnimations.add(animation);
|
||||
|
||||
view.startAnimation(animation);
|
||||
|
||||
} else {
|
||||
listener.onAnimationEnd();
|
||||
}
|
||||
@@ -225,4 +245,23 @@ public class LayoutAnimationController {
|
||||
sCompletionHandler.postDelayed(mCompletionRunnable, delayMillis);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Animate a view deletion using the layout animation configuration supplied during
|
||||
* initialization.
|
||||
*
|
||||
* @param viewTag tag of parent view that we're going to cancel all child animations.
|
||||
*/
|
||||
public void cancelAnimationsForViewTag(int viewTag) {
|
||||
ArrayList<Animation> animations = mDeleteAnimationsByParentTag.get(viewTag);
|
||||
if (animations == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = 0; i < animations.size(); i++) {
|
||||
animations.get(i).cancel();
|
||||
}
|
||||
|
||||
mDeleteAnimationsByParentTag.remove(viewTag);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user