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
 import com.reactnativenavigation.utils.RefUtils;
6
 import com.reactnativenavigation.utils.RefUtils;
7
 
7
 
8
 import java.lang.ref.WeakReference;
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
  * Created by guyc on 06/05/16.
12
  * Created by guyc on 06/05/16.
16
 public class ModalController {
14
 public class ModalController {
17
     private static ModalController sInstance;
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
     private ModalController() {
19
     private ModalController() {
22
-        mModals = new HashMap<>();
20
+        mModals = new Stack<>();
23
     }
21
     }
24
 
22
 
25
     public static synchronized ModalController getInstance() {
23
     public static synchronized ModalController getInstance() {
30
         return sInstance;
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
     public boolean isModalDisplayed() {
35
     public boolean isModalDisplayed() {
38
         return mModals.size() != 0;
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
     public RnnModal(BaseReactActivity context, Screen screen) {
33
     public RnnModal(BaseReactActivity context, Screen screen) {
34
         super(context, R.style.Modal);
34
         super(context, R.style.Modal);
35
         mScreen = screen;
35
         mScreen = screen;
36
-        ModalController.getInstance().add(this, screen.navigatorId);
36
+        ModalController.getInstance().add(this);
37
         init(context);
37
         init(context);
38
     }
38
     }
39
 
39
 
78
         if (mScreenStack.getStackSize() > 1) {
78
         if (mScreenStack.getStackSize() > 1) {
79
             mScreenStack.pop();
79
             mScreenStack.pop();
80
         } else {
80
         } else {
81
-            ModalController.getInstance().remove(mScreen.navigatorId);
81
+            ModalController.getInstance().remove();
82
             super.onBackPressed();
82
             super.onBackPressed();
83
         }
83
         }
84
     }
84
     }
85
 
85
 
86
     @Override
86
     @Override
87
     public void onDismiss(DialogInterface dialog) {
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
             return;
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
         ModalController modalController = ModalController.getInstance();
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
             if (modal != null) {
87
             if (modal != null) {
88
                 context.runOnUiThread(new Runnable() {
88
                 context.runOnUiThread(new Runnable() {
89
                     @Override
89
                     @Override
114
 
114
 
115
         // First, check if the screen should be popped from a Modal
115
         // First, check if the screen should be popped from a Modal
116
         ModalController modalController = ModalController.getInstance();
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
             if (modal != null) {
119
             if (modal != null) {
120
                 context.runOnUiThread(new Runnable() {
120
                 context.runOnUiThread(new Runnable() {
121
                     @Override
121
                     @Override
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
           <Text style={styles.button}>Pop Screen</Text>
57
           <Text style={styles.button}>Pop Screen</Text>
58
         </TouchableOpacity>
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
         <TextInput style={{height: 40, borderColor: 'gray', borderWidth: 1}}/>
73
         <TextInput style={{height: 40, borderColor: 'gray', borderWidth: 1}}/>
61
 
74
 
62
       </View>
75
       </View>
63
     );
76
     );
64
   }
77
   }
78
+
65
   onIncrementPress() {
79
   onIncrementPress() {
66
     this.props.dispatch(counterActions.increment());
80
     this.props.dispatch(counterActions.increment());
67
   }
81
   }
82
+
68
   onPushPress() {
83
   onPushPress() {
69
     this.props.navigator.push({
84
     this.props.navigator.push({
70
       title: "More",
85
       title: "More",
71
       screen: "example.PushedScreen"
86
       screen: "example.PushedScreen"
72
     });
87
     });
73
   }
88
   }
89
+
74
   onPopPress() {
90
   onPopPress() {
75
     this.props.navigator.pop();
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
 const styles = StyleSheet.create({
110
 const styles = StyleSheet.create({

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

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

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

358
           passProps={passProps}
358
           passProps={passProps}
359
           style={navigatorStyle}
359
           style={navigatorStyle}
360
           leftButtons={navigatorButtons.leftButtons}
360
           leftButtons={navigatorButtons.leftButtons}
361
-          rightButtons={navigatorButtons.rightButtons}
362
-        />
361
+          rightButtons={navigatorButtons.rightButtons}/>
363
       );
362
       );
364
     }
363
     }
365
   });
364
   });