ソースを参照

Fix YellowBox handling in TopBar components on RN >= 0.56

This commit includes two fixes to YellowBox handling:

1. RN started throwing exceptions when views added in JSX were removed from hierarchy.
    We could probably use UiManager to fiddle around with the yellow box, either removing it or making
    it hidden and allow touch events to pass through it. For now, we continue removing yellow boxes from hierarchy
    and we replace the removed yellow boxed with dummy views.
2. A “Dismiss All” button was recently added, we remove that as well.

Fixes #4035
Guy Carmeli 6 年 前
コミット
fee8d1966d

+ 1
- 1
e2e/ScreenStyle.test.js ファイルの表示

@@ -184,7 +184,7 @@ describe('screen style', () => {
184 184
     await expect(elementById(testIDs.TOP_BAR_BUTTON)).toBeVisible();
185 185
   });
186 186
 
187
-  test(':android: Popping screen with yellow box in button, title and background components should not crash', async () => {
187
+  test('Popping screen with yellow box in button, title and background components should not crash', async () => {
188 188
     await elementById(testIDs.PUSH_OPTIONS_BUTTON).tap();
189 189
     await elementById(testIDs.SHOW_YELLOW_BOX).tap();
190 190
     Android.pressBack();

+ 26
- 17
lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/YellowBoxDelegate.java ファイルの表示

@@ -4,11 +4,14 @@ import android.support.annotation.RestrictTo;
4 4
 import android.view.View;
5 5
 import android.view.ViewGroup;
6 6
 
7
+import java.util.ArrayList;
8
+import java.util.List;
9
+
7 10
 public class YellowBoxDelegate {
8 11
     private ViewGroup parent;
9
-    private View yellowBox;
10 12
     private YellowBoxHelper yellowBoxHelper;
11 13
     private boolean isDestroyed;
14
+    private ArrayList<View> yellowBoxViews = new ArrayList<>();
12 15
 
13 16
     public YellowBoxDelegate() {
14 17
         this.yellowBoxHelper = new YellowBoxHelper();
@@ -18,33 +21,39 @@ public class YellowBoxDelegate {
18 21
         this.yellowBoxHelper = yellowBoxHelper;
19 22
     }
20 23
 
21
-    @RestrictTo(RestrictTo.Scope.TESTS)
22
-    public ViewGroup getParent() {
23
-        return parent;
24
-    }
25
-
26
-    @RestrictTo(RestrictTo.Scope.TESTS)
27
-    public View getYellowBox() {
28
-        return yellowBox;
29
-    }
30
-
31 24
     public void onChildViewAdded(View parent, View child) {
32 25
         if (yellowBoxHelper.isYellowBox(parent, child)) {
33
-            onYellowBoxAdded(parent, child);
26
+            onYellowBoxAdded(parent);
34 27
         }
35 28
     }
36 29
 
37
-    protected void onYellowBoxAdded(View parent, View yellowBox) {
30
+    void onYellowBoxAdded(View parent) {
38 31
         if (isDestroyed) return;
39
-        this.yellowBox = yellowBox;
40 32
         this.parent = (ViewGroup) parent;
41
-        this.parent.removeView(yellowBox);
33
+
34
+        for (int i = 1; i < this.parent.getChildCount(); i++) {
35
+            yellowBoxViews.add(this.parent.getChildAt(i));
36
+            this.parent.removeView(this.parent.getChildAt(i));
37
+            this.parent.addView(new View(parent.getContext()), i);
38
+        }
42 39
     }
43 40
 
44 41
     public void destroy() {
45 42
         isDestroyed = true;
46
-        if (yellowBox != null) {
47
-            parent.addView(yellowBox);
43
+        if (!yellowBoxViews.isEmpty()) {
44
+            for (View view : yellowBoxViews) {
45
+                parent.addView(view);
46
+            }
48 47
         }
49 48
     }
49
+
50
+    @RestrictTo(RestrictTo.Scope.TESTS)
51
+    public ViewGroup getParent() {
52
+        return parent;
53
+    }
54
+
55
+    @RestrictTo(RestrictTo.Scope.TESTS)
56
+    public List<View> getYellowBoxes() {
57
+        return yellowBoxViews;
58
+    }
50 59
 }

+ 2
- 2
lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/YellowBoxHelper.java ファイルの表示

@@ -13,8 +13,8 @@ public class YellowBoxHelper {
13 13
     public boolean isYellowBox(View parent, View child) {
14 14
         return parent instanceof ViewGroup &&
15 15
                child instanceof ViewGroup &&
16
-                ((ViewGroup) parent).getChildCount() > 1 &&
17
-               !ViewUtils.findChildrenByClassRecursive(((ViewGroup) child), View.class, YellowBackgroundMather()).isEmpty();
16
+               ((ViewGroup) parent).getChildCount() > 1 &&
17
+               !ViewUtils.findChildrenByClassRecursive((ViewGroup) child, View.class, YellowBackgroundMather()).isEmpty();
18 18
     }
19 19
 
20 20
     @NonNull

+ 0
- 1
lib/android/app/src/reactNative57/java/com/reactnativenavigation/react/NavigationReactNativeHost.java ファイルの表示

@@ -35,7 +35,6 @@ public class NavigationReactNativeHost extends ReactNativeHost implements Bundle
35 35
         }
36 36
     };
37 37
 
38
-
39 38
     public NavigationReactNativeHost(NavigationApplication application) {
40 39
         this(application, application.isDebug(), application.createAdditionalReactPackages());
41 40
     }

+ 7
- 6
lib/android/app/src/test/java/com/reactnativenavigation/viewcontrollers/YellowBoxDelegateTest.java ファイルの表示

@@ -26,25 +26,26 @@ public class YellowBoxDelegateTest extends BaseTest {
26 26
         parent = new FrameLayout(context);
27 27
         yellowBoxHelper = Mockito.mock(YellowBoxHelper.class);
28 28
         uut = new YellowBoxDelegate(yellowBoxHelper);
29
+        parent.addView(new View(context)); // We assume view at index 0 is not a yellow box
29 30
         parent.addView(yellowBox);
30 31
     }
31 32
 
32 33
     @Test
33 34
     public void onYellowBoxAdded_removedFromParent() {
34
-        uut.onYellowBoxAdded(parent, yellowBox);
35
+        uut.onYellowBoxAdded(parent);
35 36
         assertThat(yellowBox.getParent()).isNull();
36 37
     }
37 38
 
38 39
     @Test
39 40
     public void onYellowBoxAdded_storesRefToYellowBoxAndParent() {
40
-        uut.onYellowBoxAdded(parent, yellowBox);
41
-        assertThat(uut.getYellowBox()).isEqualTo(yellowBox);
41
+        uut.onYellowBoxAdded(parent);
42
+        assertThat(uut.getYellowBoxes()).contains(yellowBox);
42 43
         assertThat(uut.getParent()).isEqualTo(parent);
43 44
     }
44 45
 
45 46
     @Test
46 47
     public void onReactViewDestroy_yellowBoxIsAddedBackToParent() {
47
-        uut.onYellowBoxAdded(parent, yellowBox);
48
+        uut.onYellowBoxAdded(parent);
48 49
         uut.destroy();
49 50
         assertThat(yellowBox.getParent()).isEqualTo(parent);
50 51
     }
@@ -57,10 +58,10 @@ public class YellowBoxDelegateTest extends BaseTest {
57 58
 
58 59
     @Test
59 60
     public void onYellowBoxAdded_notHandledIfDelegateIsDestroyed() {
60
-        uut.onYellowBoxAdded(parent, yellowBox);
61
+        uut.onYellowBoxAdded(parent);
61 62
         uut.destroy();
62 63
 
63
-        uut.onYellowBoxAdded(parent, yellowBox);
64
+        uut.onYellowBoxAdded(parent);
64 65
         assertThat(yellowBox.getParent()).isEqualTo(parent);
65 66
     }
66 67
 }