22
22
import android .view .MotionEvent ;
23
23
import android .view .View ;
24
24
import android .view .ViewGroup ;
25
+ import android .view .ViewParent ;
25
26
import android .view .ViewStructure ;
26
27
import android .view .animation .Animation ;
27
28
import androidx .annotation .Nullable ;
56
57
import com .facebook .react .uimanager .style .BorderStyle ;
57
58
import com .facebook .react .uimanager .style .LogicalEdge ;
58
59
import com .facebook .react .uimanager .style .Overflow ;
60
+ import java .util .HashSet ;
61
+ import java .util .Set ;
59
62
60
63
/**
61
64
* 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) {
409
412
try {
410
413
updateSubviewClipStatus (clippingRect , i , clippedSoFar );
411
414
} 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
+
412
422
throw new IllegalStateException (
413
423
"Invalid clipping state. i="
414
424
+ i
@@ -419,7 +429,11 @@ private void updateClippingToRect(Rect clippingRect) {
419
429
+ " allChildrenCount="
420
430
+ mAllChildrenCount
421
431
+ " recycleCount="
422
- + mRecycleCount ,
432
+ + mRecycleCount
433
+ + " realClippedSoFar="
434
+ + realClippedSoFar
435
+ + " uniqueViewsCount="
436
+ + uniqueViews .size (),
423
437
e );
424
438
}
425
439
if (isViewClipped (mAllChildren [i ])) {
@@ -450,7 +464,9 @@ private void updateSubviewClipStatus(Rect clippingRect, int idx, int clippedSoFa
450
464
removeViewInLayout (child );
451
465
needUpdateClippingRecursive = true ;
452
466
} 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 );
454
470
invalidate ();
455
471
needUpdateClippingRecursive = true ;
456
472
} else if (intersects ) {
@@ -694,7 +710,13 @@ public void run() {
694
710
* @return {@code true} if the view has been removed from the ViewGroup.
695
711
*/
696
712
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
+ }
698
720
}
699
721
700
722
private int indexOfChildInAllChildren (View child ) {
0 commit comments