Browse Source

Android: Fix an issue with incorrect Lightbox measurments. (#2625)

Due to a race condition, the height and width of the Lightbox screen
may be read too early, resulting in a zero-width or height lightbox.

Addresses Content of lightbox not displayed #2288
Jon Bettcher 6 years ago
parent
commit
b3ba7c5cd5
1 changed files with 31 additions and 17 deletions
  1. 31
    17
      android/app/src/main/java/com/reactnativenavigation/views/LightBox.java

+ 31
- 17
android/app/src/main/java/com/reactnativenavigation/views/LightBox.java View File

@@ -13,13 +13,13 @@ import android.support.v4.view.animation.FastOutSlowInInterpolator;
13 13
 import android.support.v7.app.AppCompatActivity;
14 14
 import android.view.View;
15 15
 import android.view.ViewGroup;
16
+import android.view.ViewTreeObserver;
16 17
 import android.view.Window;
17 18
 import android.view.WindowManager;
18 19
 import android.widget.RelativeLayout;
19 20
 
20 21
 import com.reactnativenavigation.R;
21 22
 import com.reactnativenavigation.params.LightBoxParams;
22
-import com.reactnativenavigation.screens.Screen;
23 23
 import com.reactnativenavigation.utils.ViewUtils;
24 24
 
25 25
 import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
@@ -48,14 +48,18 @@ public class LightBox extends Dialog implements DialogInterface.OnDismissListene
48 48
         }
49 49
     }
50 50
 
51
-    private void createContent(final Context context, LightBoxParams params) {
51
+    private void createContent(final Context context, final LightBoxParams params) {
52 52
         lightBox = new RelativeLayout(context);
53 53
         lightBox.setAlpha(0);
54
-        content = new ContentView(context, params.screenId, params.navigationParams);
55
-        content.setAlpha(0);
54
+        lightBox.setBackgroundColor(params.backgroundColor.getColor());
55
+
56 56
         RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(WRAP_CONTENT, WRAP_CONTENT);
57
+        lp.width = WindowManager.LayoutParams.MATCH_PARENT;
58
+        lp.height = WindowManager.LayoutParams.MATCH_PARENT;
59
+
60
+        content = new ContentView(context, params.screenId, params.navigationParams);
57 61
         lp.addRule(RelativeLayout.CENTER_IN_PARENT, content.getId());
58
-        lightBox.setBackgroundColor(params.backgroundColor.getColor());
62
+        content.setAlpha(0);
59 63
         lightBox.addView(content, lp);
60 64
 
61 65
         if (params.tapBackgroundToDismiss) {
@@ -66,20 +70,29 @@ public class LightBox extends Dialog implements DialogInterface.OnDismissListene
66 70
                 }
67 71
             });
68 72
         }
69
-
70
-        content.setOnDisplayListener(new Screen.OnDisplayListener() {
73
+        content.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
71 74
             @Override
72
-            public void onDisplay() {
73
-                content.getLayoutParams().height = content.getChildAt(0).getHeight();
74
-                content.getLayoutParams().width = content.getChildAt(0).getWidth();
75
-                content.setBackgroundColor(Color.TRANSPARENT);
76
-                ViewUtils.runOnPreDraw(content, new Runnable() {
77
-                    @Override
78
-                    public void run() {
79
-                        animateShow();
75
+            public void onGlobalLayout() {
76
+                // Note that this may be called multiple times as the lightbox views get built.  We want to hold off
77
+                // doing anything here until the lightbox screen and its measurements are available.
78
+                final View lightboxScreen = content.getChildAt(0);
79
+                if (lightboxScreen != null) {
80
+                    final int screenHeight = lightboxScreen.getHeight();
81
+                    final int screenWidth = lightboxScreen.getWidth();
82
+                    if (screenHeight > 0 && screenWidth > 0) {
83
+                        content.getViewTreeObserver().removeOnGlobalLayoutListener(this);
84
+                        content.getLayoutParams().height = screenHeight;
85
+                        content.getLayoutParams().width = screenWidth;
86
+                        content.setBackgroundColor(Color.TRANSPARENT);
87
+                        ViewUtils.runOnPreDraw(content, new Runnable() {
88
+                            @Override
89
+                            public void run() {
90
+                                animateShow();
91
+                            }
92
+                        });
80 93
 
81 94
                     }
82
-                });
95
+                }
83 96
             }
84 97
         });
85 98
         setContentView(lightBox, new ViewGroup.LayoutParams(MATCH_PARENT, MATCH_PARENT));
@@ -95,7 +108,8 @@ public class LightBox extends Dialog implements DialogInterface.OnDismissListene
95 108
         animateHide();
96 109
     }
97 110
 
98
-    @Override public void onBackPressed() {
111
+    @Override
112
+    public void onBackPressed() {
99 113
         if (cancelable) {
100 114
             hide();
101 115
         }