Browse Source

Adds support for passing props in Android

Anything passed in a navigator event in a 'passProps' object will be serialized into the Java side Screen object as a HashMap<String, Object>. When RctView starts the React root the props are deserialized into the Bundle passed as props, along with the navigation info. Due to React and Java limitations, JS arrays of arrays are deserialized as dictionaries by index, and arrays of multiple types are not supported.
Yedidya Kennard 8 years ago
parent
commit
47b77f07b5

+ 3
- 0
.gitignore View File

@@ -145,3 +145,6 @@ xcuserdata
145 145
 # UNKNOWN: recommended by others, but I can't discover what these files are
146 146
 #
147 147
 # ...none. Everything is now explained.:
148
+android/gradlew
149
+android/gradlew.bat
150
+android/local.properties

+ 116
- 0
android/app/src/main/java/com/reactnativenavigation/utils/BridgeUtils.java View File

@@ -0,0 +1,116 @@
1
+package com.reactnativenavigation.utils;
2
+
3
+import android.os.Bundle;
4
+import android.util.Log;
5
+
6
+import java.util.ArrayList;
7
+import java.util.HashMap;
8
+
9
+/**
10
+ * Created by yedidyak on 26/05/2016.
11
+ */
12
+public class BridgeUtils {
13
+
14
+    @SuppressWarnings("unchecked")
15
+    public static Bundle addMapToBundle(HashMap<String, ?> map, Bundle bundle) {
16
+        for (String key : map.keySet()) {
17
+            Object value = map.get(key);
18
+            if (value instanceof String) {
19
+                bundle.putString(key, (String) value);
20
+            } else if (value instanceof Integer) {
21
+                bundle.putInt(key, (Integer) value);
22
+            } else if (value instanceof Double) {
23
+                bundle.putDouble(key, ((Double) value));
24
+            } else if (value instanceof Boolean) {
25
+                bundle.putBoolean(key, (Boolean) value);
26
+            } else if (value instanceof HashMap) {
27
+                bundle.putBundle(key, addMapToBundle((HashMap<String, Object>) value, new Bundle()));
28
+            } else if (value instanceof ArrayList) {
29
+                putArray(key, (ArrayList) value, bundle);
30
+            }
31
+        }
32
+        return bundle;
33
+    }
34
+
35
+    @SuppressWarnings("unchecked")
36
+    private static void putArray(String key, ArrayList arrayList, Bundle bundle) {
37
+        if (arrayList.size() == 0) {
38
+            bundle.putBooleanArray(key, new boolean[]{});
39
+        } else {
40
+            verifyArrayListIsSingleType(arrayList);
41
+            if (arrayList.get(0) instanceof String) {
42
+                bundle.putStringArray(key, toStringArray((ArrayList<String>) arrayList));
43
+            } else if (arrayList.get(0) instanceof Integer) {
44
+                bundle.putIntArray(key, toIntArray((ArrayList<Integer>) arrayList));
45
+            } else if (arrayList.get(0) instanceof Float) {
46
+                bundle.putFloatArray(key, toFloatArray((ArrayList<Float>) arrayList));
47
+            } else if (arrayList.get(0) instanceof Double) {
48
+                bundle.putDoubleArray(key, toDoubleArray((ArrayList<Double>) arrayList));
49
+            } else if (arrayList.get(0) instanceof Boolean) {
50
+                bundle.putBooleanArray(key, toBooleanArray((ArrayList<Boolean>) arrayList));
51
+            } else if (arrayList.get(0) instanceof HashMap) {
52
+                bundle.putParcelableArray(key, toBundleArray((ArrayList<HashMap>) arrayList));
53
+            } else if (arrayList.get(0) instanceof ArrayList) {
54
+                Log.w("RNNNavigation", "Arrays of arrays passed in props are converted to dictionaries with indexes as keys");
55
+                Bundle innerArray = new Bundle();
56
+                for (int i = 0; i < arrayList.size(); i++) {
57
+                    putArray(String.valueOf(i), (ArrayList) arrayList.get(i), innerArray);
58
+                }
59
+                bundle.putParcelable(key, innerArray);
60
+            }
61
+        }
62
+    }
63
+
64
+    private static void verifyArrayListIsSingleType(ArrayList arrayList) {
65
+        int i = 1;
66
+        while (i < arrayList.size()) {
67
+            if (!arrayList.get(i - 1).getClass().isInstance(arrayList.get(i)))
68
+                throw new IllegalArgumentException("Cannot pass array of multiple types via props");
69
+            i++;
70
+        }
71
+    }
72
+
73
+    @SuppressWarnings("unchecked")
74
+    private static Bundle[] toBundleArray(ArrayList<HashMap> arrayList) {
75
+        Bundle[] ret = new Bundle[arrayList.size()];
76
+        for (int i=0; i < ret.length; i++)
77
+            ret[i] = addMapToBundle(arrayList.get(i), new Bundle());
78
+        return ret;
79
+    }
80
+
81
+    private static int[] toIntArray(ArrayList<Integer> arrayList) {
82
+        int[] ret = new int[arrayList.size()];
83
+        for (int i=0; i < ret.length; i++)
84
+            ret[i] = arrayList.get(i);
85
+        return ret;
86
+    }
87
+
88
+    private static float[] toFloatArray(ArrayList<Float> arrayList) {
89
+        float[] ret = new float[arrayList.size()];
90
+        for (int i=0; i < ret.length; i++)
91
+            ret[i] = arrayList.get(i);
92
+        return ret;
93
+    }
94
+
95
+    private static double[] toDoubleArray(ArrayList<Double> arrayList) {
96
+        double[] ret = new double[arrayList.size()];
97
+        for (int i=0; i < ret.length; i++)
98
+            ret[i] = arrayList.get(i);
99
+        return ret;
100
+    }
101
+
102
+    private static boolean[] toBooleanArray(ArrayList<Boolean> arrayList) {
103
+        boolean[] ret = new boolean[arrayList.size()];
104
+        for (int i=0; i < ret.length; i++)
105
+            ret[i] = arrayList.get(i);
106
+        return ret;
107
+    }
108
+
109
+    private static String[] toStringArray(ArrayList<String> arrayList) {
110
+        String[] ret = new String[arrayList.size()];
111
+        for (int i=0; i < ret.length; i++)
112
+            ret[i] = arrayList.get(i);
113
+        return ret;
114
+    }
115
+
116
+}

+ 3
- 22
android/app/src/main/java/com/reactnativenavigation/views/RctView.java View File

@@ -8,8 +8,7 @@ import com.facebook.react.ReactInstanceManager;
8 8
 import com.facebook.react.ReactRootView;
9 9
 import com.reactnativenavigation.activities.BaseReactActivity;
10 10
 import com.reactnativenavigation.core.objects.Screen;
11
-
12
-import java.util.HashMap;
11
+import com.reactnativenavigation.utils.BridgeUtils;
13 12
 
14 13
 /**
15 14
  * Created by guyc on 10/03/16.
@@ -36,6 +35,7 @@ public class RctView extends FrameLayout {
36 35
         this(ctx, rctInstanceManager, screen, null);
37 36
     }
38 37
 
38
+    @SuppressWarnings("unchecked")
39 39
     public RctView(BaseReactActivity ctx, ReactInstanceManager rctInstanceManager, Screen screen,
40 40
                    final OnDisplayedListener onDisplayedListener) {
41 41
         super(ctx);
@@ -50,7 +50,7 @@ public class RctView extends FrameLayout {
50 50
         passProps.putString(Screen.KEY_NAVIGATOR_ID, screen.navigatorId);
51 51
         passProps.putString(Screen.KEY_NAVIGATOR_EVENT_ID, screen.navigatorEventId);
52 52
         if (screen.passedProps != null) {
53
-            spreadHashMap(screen.passedProps, passProps);
53
+            BridgeUtils.addMapToBundle(screen.passedProps, passProps);
54 54
         }
55 55
 
56 56
         mReactRootView.startReactApplication(rctInstanceManager, componentName, passProps);
@@ -67,24 +67,5 @@ public class RctView extends FrameLayout {
67 67
 
68 68
         addView(mReactRootView);
69 69
     }
70
-
71
-    private Bundle spreadHashMap(HashMap<String, Object> map, Bundle bundle) {
72
-        for (String key : map.keySet()) {
73
-            Object value = map.get(key);
74
-            if (value instanceof String) {
75
-                bundle.putString(key, (String) value);
76
-            } else if (value instanceof Integer) {
77
-                bundle.putInt(key, (Integer) value);
78
-            } else if (value instanceof Double) {
79
-                bundle.putDouble(key, ((Double) value).doubleValue());
80
-            } else if (value instanceof Boolean) {
81
-                bundle.putBoolean(key, (Boolean) value);
82
-            } else if (value instanceof HashMap) {
83
-                bundle.putBundle(key, spreadHashMap((HashMap<String, Object>) value, new Bundle()));
84
-                //TODO nulls and Arrays needed
85
-            }
86
-        }
87
-        return bundle;
88
-    }
89 70
 }
90 71