Cleanup native view hierarchy when view is dropped.

Differential Revision: D2659738

fb-gh-sync-id: 1c14b8c3c6fabbd0e580777bb94221df6dd98f71
This commit is contained in:
Krzysztof Magiera 2015-11-16 14:27:57 -08:00 committed by facebook-github-bot-7
parent 0f590d1233
commit bd1885b5d4
6 changed files with 47 additions and 14 deletions

View File

@ -393,12 +393,13 @@ import com.facebook.react.touch.JSResponderHandler;
if (view instanceof ViewGroup && viewManager instanceof ViewGroupManager) {
ViewGroup viewGroup = (ViewGroup) view;
ViewGroupManager viewGroupManager = (ViewGroupManager) viewManager;
for (int i = 0; i < viewGroupManager.getChildCount(viewGroup); i++) {
for (int i = viewGroupManager.getChildCount(viewGroup) - 1; i >= 0; i--) {
View child = viewGroupManager.getChildAt(viewGroup, i);
if (mTagsToViews.get(child.getId()) != null) {
dropView(child);
}
}
viewGroupManager.removeAllViews(viewGroup);
}
mTagsToViews.remove(view.getId());
mTagsToViewManagers.remove(view.getId());

View File

@ -122,16 +122,7 @@ public class ReactShadowNode extends CSSNode {
int increase = node.mIsLayoutOnly ? node.mTotalNativeChildren : 1;
mTotalNativeChildren += increase;
if (mIsLayoutOnly) {
ReactShadowNode parent = getParent();
while (parent != null) {
parent.mTotalNativeChildren += increase;
if (!parent.mIsLayoutOnly) {
break;
}
parent = parent.getParent();
}
}
updateNativeChildrenCountInParent(increase);
}
@Override
@ -141,17 +132,31 @@ public class ReactShadowNode extends CSSNode {
int decrease = removed.mIsLayoutOnly ? removed.mTotalNativeChildren : 1;
mTotalNativeChildren -= decrease;
updateNativeChildrenCountInParent(-decrease);
return removed;
}
public void removeAllChildren() {
for (int i = getChildCount() - 1; i >= 0; i--) {
super.removeChildAt(i);
}
markUpdated();
updateNativeChildrenCountInParent(-mTotalNativeChildren);
mTotalNativeChildren = 0;
}
private void updateNativeChildrenCountInParent(int delta) {
if (mIsLayoutOnly) {
ReactShadowNode parent = getParent();
while (parent != null) {
parent.mTotalNativeChildren -= decrease;
parent.mTotalNativeChildren -= delta;
if (!parent.mIsLayoutOnly) {
break;
}
parent = parent.getParent();
}
}
return removed;
}
/**

View File

@ -406,9 +406,10 @@ public class UIManagerModule extends ReactContextBaseJavaModule implements
private void removeCSSNode(int tag) {
ReactShadowNode node = mShadowNodeRegistry.getNode(tag);
mShadowNodeRegistry.removeNode(tag);
for (int i = 0;i < node.getChildCount(); i++) {
for (int i = node.getChildCount() - 1; i >= 0; i--) {
removeCSSNode(node.getChildAt(i).getReactTag());
}
node.removeAllChildren();
}
/**

View File

@ -48,6 +48,12 @@ public abstract class ViewGroupManager <T extends ViewGroup>
parent.removeViewAt(index);
}
public void removeAllViews(T parent) {
for (int i = getChildCount(parent) - 1; i >= 0; i--) {
removeViewAt(parent, i);
}
}
/**
* Returns whether this View type needs to handle laying out its own children instead of
* deferring to the standard css-layout algorithm.

View File

@ -403,6 +403,16 @@ public class ReactViewGroup extends ViewGroup implements
removeFromArray(index);
}
/*package*/ void removeAllViewsWithSubviewClippingEnabled() {
Assertions.assertCondition(mRemoveClippedSubviews);
Assertions.assertNotNull(mAllChildren);
for (int i = 0; i < mAllChildrenCount; i++) {
mAllChildren[i].removeOnLayoutChangeListener(mChildrenLayoutChangeListener);
}
removeAllViewsInLayout();
mAllChildrenCount = 0;
}
private int indexOfChildInAllChildren(View child) {
final int count = mAllChildrenCount;
final View[] children = Assertions.assertNotNull(mAllChildren);

View File

@ -207,4 +207,14 @@ public class ReactViewManager extends ViewGroupManager<ReactViewGroup> {
parent.removeViewAt(index);
}
}
@Override
public void removeAllViews(ReactViewGroup parent) {
boolean removeClippedSubviews = parent.getRemoveClippedSubviews();
if (removeClippedSubviews) {
parent.removeAllViewsWithSubviewClippingEnabled();
} else {
parent.removeAllViews();
}
}
}