2222import android .view .MotionEvent ;
2323import android .view .View ;
2424import android .view .ViewGroup ;
25+ import android .view .ViewParent ;
2526import android .view .ViewStructure ;
2627import android .view .animation .Animation ;
2728import androidx .annotation .Nullable ;
5657import com .facebook .react .uimanager .style .BorderStyle ;
5758import com .facebook .react .uimanager .style .LogicalEdge ;
5859import com .facebook .react .uimanager .style .Overflow ;
60+ import java .util .HashSet ;
61+ import java .util .Set ;
5962
6063/**
6164 * Backing for a React View. Has support for borders, but since borders aren't common, lazy
@@ -409,6 +412,13 @@ private void updateClippingToRect(Rect clippingRect) {
409412 try {
410413 updateSubviewClipStatus (clippingRect , i , clippedSoFar );
411414 } catch (IndexOutOfBoundsException e ) {
415+ int realClippedSoFar = 0 ;
416+ Set <View > uniqueViews = new HashSet <>();
417+ for (int j = 0 ; j < i ; j ++) {
418+ realClippedSoFar += isViewClipped (mAllChildren [j ]) ? 1 : 0 ;
419+ uniqueViews .add (mAllChildren [j ]);
420+ }
421+
412422 throw new IllegalStateException (
413423 "Invalid clipping state. i="
414424 + i
@@ -419,7 +429,11 @@ private void updateClippingToRect(Rect clippingRect) {
419429 + " allChildrenCount="
420430 + mAllChildrenCount
421431 + " recycleCount="
422- + mRecycleCount ,
432+ + mRecycleCount
433+ + " realClippedSoFar="
434+ + realClippedSoFar
435+ + " uniqueViewsCount="
436+ + uniqueViews .size (),
423437 e );
424438 }
425439 if (isViewClipped (mAllChildren [i ])) {
@@ -450,7 +464,9 @@ private void updateSubviewClipStatus(Rect clippingRect, int idx, int clippedSoFa
450464 removeViewInLayout (child );
451465 needUpdateClippingRecursive = true ;
452466 } else if (intersects && isViewClipped (child )) {
453- addViewInLayout (child , idx - clippedSoFar , sDefaultLayoutParam , true );
467+ int adjustedIdx = idx - clippedSoFar ;
468+ Assertions .assertCondition (adjustedIdx >= 0 );
469+ addViewInLayout (child , adjustedIdx , sDefaultLayoutParam , true );
454470 invalidate ();
455471 needUpdateClippingRecursive = true ;
456472 } else if (intersects ) {
@@ -694,7 +710,13 @@ public void run() {
694710 * @return {@code true} if the view has been removed from the ViewGroup.
695711 */
696712 private boolean isViewClipped (View view ) {
697- return view .getParent () == null ;
713+ ViewParent parent = view .getParent ();
714+ if (parent == null ) {
715+ return true ;
716+ } else {
717+ Assertions .assertCondition (parent == this );
718+ return false ;
719+ }
698720 }
699721
700722 private int indexOfChildInAllChildren (View child ) {
0 commit comments