Browse Source

Add dismissModal method to Android

Also changed the structure used to store Modals
from a Map based on navigatorId to a stack.
Reason for the change is that screens can be
pushed only to the topmost Modal.
Guy Carmeli 8 years ago
parent
commit
bd35145c99

+ 19
- 26
android/app/src/main/java/com/reactnativenavigation/controllers/ModalController.java View File

@@ -6,9 +6,7 @@ import com.reactnativenavigation.modal.RnnModal;
6 6
 import com.reactnativenavigation.utils.RefUtils;
7 7
 
8 8
 import java.lang.ref.WeakReference;
9
-import java.util.HashMap;
10
-import java.util.Iterator;
11
-import java.util.Map;
9
+import java.util.Stack;
12 10
 
13 11
 /**
14 12
  * Created by guyc on 06/05/16.
@@ -16,10 +14,10 @@ import java.util.Map;
16 14
 public class ModalController {
17 15
     private static ModalController sInstance;
18 16
 
19
-    private final Map<String, WeakReference<RnnModal>> mModals;
17
+    private final Stack<WeakReference<RnnModal>> mModals;
20 18
 
21 19
     private ModalController() {
22
-        mModals = new HashMap<>();
20
+        mModals = new Stack<>();
23 21
     }
24 22
 
25 23
     public static synchronized ModalController getInstance() {
@@ -30,41 +28,36 @@ public class ModalController {
30 28
         return sInstance;
31 29
     }
32 30
 
33
-    public void add(RnnModal modal, String navigatorId) {
34
-        mModals.put(navigatorId, new WeakReference<>(modal));
31
+    public void add(RnnModal modal) {
32
+        mModals.add(new WeakReference<>(modal));
35 33
     }
36 34
 
37 35
     public boolean isModalDisplayed() {
38 36
         return mModals.size() != 0;
39 37
     }
40 38
 
41
-    public boolean isModalDisplayed(String navigatorId) {
42
-        return mModals.size() != 0 && mModals.containsKey(navigatorId);
39
+    @Nullable
40
+    public RnnModal get() {
41
+        return isModalDisplayed() ? RefUtils.get(mModals.peek()) : null;
43 42
     }
44 43
 
45
-    @Nullable
46
-    public RnnModal get(String navigatorId) {
47
-        if (mModals.containsKey(navigatorId)) {
48
-            return RefUtils.get(mModals.get(navigatorId));
44
+    public void remove() {
45
+        if (isModalDisplayed()) {
46
+            mModals.pop();
49 47
         }
50
-
51
-        return null;
52 48
     }
53 49
 
54
-    public void remove(String navigatorId) {
55
-        if (mModals.containsKey(navigatorId)) {
56
-            mModals.remove(navigatorId);
50
+    public void dismissAllModals() {
51
+        while (isModalDisplayed()) {
52
+            dismissModal();
57 53
         }
58 54
     }
59 55
 
60
-    public void dismissAllModals() {
61
-        Iterator<String> iterator = mModals.keySet().iterator();
62
-        while (iterator.hasNext()) {
63
-            WeakReference<RnnModal> ref = mModals.get(iterator.next());
64
-            RnnModal modal = RefUtils.get(ref);
65
-            if (modal != null) {
66
-                modal.dismiss();
67
-            }
56
+    public void dismissModal() {
57
+        WeakReference<RnnModal> ref = mModals.pop();
58
+        RnnModal modal = RefUtils.get(ref);
59
+        if (modal != null) {
60
+            modal.dismiss();
68 61
         }
69 62
     }
70 63
 }

+ 3
- 3
android/app/src/main/java/com/reactnativenavigation/modal/RnnModal.java View File

@@ -33,7 +33,7 @@ public class RnnModal extends Dialog implements DialogInterface.OnDismissListene
33 33
     public RnnModal(BaseReactActivity context, Screen screen) {
34 34
         super(context, R.style.Modal);
35 35
         mScreen = screen;
36
-        ModalController.getInstance().add(this, screen.navigatorId);
36
+        ModalController.getInstance().add(this);
37 37
         init(context);
38 38
     }
39 39
 
@@ -78,13 +78,13 @@ public class RnnModal extends Dialog implements DialogInterface.OnDismissListene
78 78
         if (mScreenStack.getStackSize() > 1) {
79 79
             mScreenStack.pop();
80 80
         } else {
81
-            ModalController.getInstance().remove(mScreen.navigatorId);
81
+            ModalController.getInstance().remove();
82 82
             super.onBackPressed();
83 83
         }
84 84
     }
85 85
 
86 86
     @Override
87 87
     public void onDismiss(DialogInterface dialog) {
88
-        ModalController.getInstance().remove(mScreen.navigatorId);
88
+        ModalController.getInstance().remove();
89 89
     }
90 90
 }

+ 17
- 5
android/app/src/main/java/com/reactnativenavigation/modules/RctActivityModule.java View File

@@ -80,10 +80,10 @@ public class RctActivityModule extends ReactContextBaseJavaModule {
80 80
             return;
81 81
         }
82 82
 
83
-        // First, check is the screen should be displayed in a Modal
83
+        // First, check if the screen should be pushed to a Modal
84 84
         ModalController modalController = ModalController.getInstance();
85
-        if (modalController.isModalDisplayed(screen.navigatorId)) {
86
-            final RnnModal modal = modalController.get(screen.navigatorId);
85
+        if (modalController.isModalDisplayed()) {
86
+            final RnnModal modal = modalController.get();
87 87
             if (modal != null) {
88 88
                 context.runOnUiThread(new Runnable() {
89 89
                     @Override
@@ -114,8 +114,8 @@ public class RctActivityModule extends ReactContextBaseJavaModule {
114 114
 
115 115
         // First, check if the screen should be popped from a Modal
116 116
         ModalController modalController = ModalController.getInstance();
117
-        if (modalController.isModalDisplayed(navigatorId)) {
118
-            final RnnModal modal = modalController.get(navigatorId);
117
+        if (modalController.isModalDisplayed()) {
118
+            final RnnModal modal = modalController.get();
119 119
             if (modal != null) {
120 120
                 context.runOnUiThread(new Runnable() {
121 121
                     @Override
@@ -163,4 +163,16 @@ public class RctActivityModule extends ReactContextBaseJavaModule {
163 163
         });
164 164
         }
165 165
     }
166
+
167
+
168
+    /**
169
+     * Dismisses the top modal (the last modal pushed).
170
+     */
171
+    @ReactMethod
172
+    public void dismissModal() {
173
+        ModalController modalController = ModalController.getInstance();
174
+        if (modalController.isModalDisplayed()) {
175
+            modalController.dismissModal();
176
+        }
177
+    }
166 178
 }

+ 31
- 0
example-redux/src/screens/PushedScreen.js View File

@@ -57,23 +57,54 @@ class PushedScreen extends Component {
57 57
           <Text style={styles.button}>Pop Screen</Text>
58 58
         </TouchableOpacity>
59 59
 
60
+        <TouchableOpacity onPress={ this.onShowModalPress.bind(this) }>
61
+          <Text style={styles.button}>Modal Screen</Text>
62
+        </TouchableOpacity>
63
+
64
+        <TouchableOpacity onPress={ this.onDismissModal.bind(this) }>
65
+          <Text style={styles.button}>Dismiss modal</Text>
66
+        </TouchableOpacity>
67
+
68
+
69
+        <TouchableOpacity onPress={ this.onDismissAllModalsPress.bind(this) }>
70
+          <Text style={styles.button}>Dismiss all modals</Text>
71
+        </TouchableOpacity>
72
+
60 73
         <TextInput style={{height: 40, borderColor: 'gray', borderWidth: 1}}/>
61 74
 
62 75
       </View>
63 76
     );
64 77
   }
78
+
65 79
   onIncrementPress() {
66 80
     this.props.dispatch(counterActions.increment());
67 81
   }
82
+
68 83
   onPushPress() {
69 84
     this.props.navigator.push({
70 85
       title: "More",
71 86
       screen: "example.PushedScreen"
72 87
     });
73 88
   }
89
+
74 90
   onPopPress() {
75 91
     this.props.navigator.pop();
76 92
   }
93
+
94
+  onShowModalPress() {
95
+    this.props.navigator.showModal({
96
+      title: "Modal Screen",
97
+      screen: "example.PushedScreen"
98
+    });
99
+  }
100
+
101
+  onDismissAllModalsPress() {
102
+    this.props.navigator.dismissAllModals();
103
+  }
104
+
105
+  onDismissModal() {
106
+    this.props.navigator.dismissModal();
107
+  }
77 108
 }
78 109
 
79 110
 const styles = StyleSheet.create({

+ 5
- 0
src/platformSpecific.android.js View File

@@ -58,6 +58,10 @@ function showModal(params) {
58 58
   RctActivity.showModal(params);
59 59
 }
60 60
 
61
+function dismissModal() {
62
+  RctActivity.dismissModal();
63
+}
64
+
61 65
 function dismissAllModals(params) {
62 66
   RctActivity.dismissAllModals(params.animationType);
63 67
 }
@@ -96,5 +100,6 @@ export default {
96 100
   navigatorPush,
97 101
   navigatorPop,
98 102
   showModal,
103
+  dismissModal,
99 104
   dismissAllModals
100 105
 }

+ 1
- 2
src/platformSpecific.ios.js View File

@@ -358,8 +358,7 @@ function showModal(params) {
358 358
           passProps={passProps}
359 359
           style={navigatorStyle}
360 360
           leftButtons={navigatorButtons.leftButtons}
361
-          rightButtons={navigatorButtons.rightButtons}
362
-        />
361
+          rightButtons={navigatorButtons.rightButtons}/>
363 362
       );
364 363
     }
365 364
   });