Skip to content

Commit 8e2906a

Browse files
kraffslolFacebook Github Bot 8
authored andcommitted
Android: Implement cancelable option for Alerts
Summary: **Motivation** In iOS you cannot dismiss alerts by clicking outside of their box, while on Android you can. This can create some inconsistency if you want to have identical behavior on both platforms. This change makes it possible for Android apps to have irremovable/required alert boxes just like in iOS. This adds an additional parameter to the Alert method. The way to use it is by providing an object with the cancelable property. The cancelable property accepts a boolean value. This utilizes the Android DialogFragment method [setCancelable](https://developer.android.com/reference/android/app/DialogFragment.html#setCancelable(boolean)) **Usage example** ```js Alert.alert( 'Alert Title', null, [ {text: 'OK', onPress: () => console.log('OK Pressed!')}, ], { cancelable: false } ); ``` **Test plan (required)** I added an additional alert to the UIExplorer project where it can be tested. I also added a part in the Dialog Module test to make sure setting canc Closes #8652 Differential Revision: D3690093 fbshipit-source-id: 4cf6cfc56f464b37ce88451acf33413393454721
1 parent 44b3cfe commit 8e2906a

File tree

4 files changed

+38
-1
lines changed

4 files changed

+38
-1
lines changed

Examples/UIExplorer/js/AlertExample.js

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,21 @@ class SimpleAlertExampleBlock extends React.Component {
106106
<Text>Alert with too many buttons</Text>
107107
</View>
108108
</TouchableHighlight>
109+
<TouchableHighlight style={styles.wrapper}
110+
onPress={() => Alert.alert(
111+
'Alert Title',
112+
null,
113+
[
114+
{text: 'OK', onPress: () => console.log('OK Pressed!')},
115+
],
116+
{
117+
cancelable: false
118+
}
119+
)}>
120+
<View style={styles.button}>
121+
<Text>Alert that cannot be dismissed</Text>
122+
</View>
123+
</TouchableHighlight>
109124
</View>
110125
);
111126
}

Libraries/Utilities/Alert.js

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,10 @@ type Buttons = Array<{
2323
style?: AlertButtonStyle;
2424
}>;
2525

26+
type Options = {
27+
cancelable?: ?boolean;
28+
};
29+
2630
/**
2731
* Launches an alert dialog with the specified title and message.
2832
*
@@ -67,6 +71,7 @@ class Alert {
6771
title: ?string,
6872
message?: ?string,
6973
buttons?: Buttons,
74+
options?: Options,
7075
type?: AlertType,
7176
): void {
7277
if (Platform.OS === 'ios') {
@@ -77,7 +82,7 @@ class Alert {
7782
}
7883
AlertIOS.alert(title, message, buttons);
7984
} else if (Platform.OS === 'android') {
80-
AlertAndroid.alert(title, message, buttons);
85+
AlertAndroid.alert(title, message, buttons, options);
8186
}
8287
}
8388
}
@@ -91,11 +96,16 @@ class AlertAndroid {
9196
title: ?string,
9297
message?: ?string,
9398
buttons?: Buttons,
99+
options?: Options,
94100
): void {
95101
var config = {
96102
title: title || '',
97103
message: message || '',
98104
};
105+
106+
if (options) {
107+
config = {...config, cancelable: options.cancelable};
108+
}
99109
// At most three buttons (neutral, negative, positive). Ignore rest.
100110
// The text 'OK' should be probably localized. iOS Alert does that in native.
101111
var validButtons: Buttons = buttons ? buttons.slice(0, 3) : [{text: 'OK'}];

ReactAndroid/src/main/java/com/facebook/react/modules/dialog/DialogModule.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ public class DialogModule extends ReactContextBaseJavaModule implements Lifecycl
4646
/* package */ static final String KEY_BUTTON_NEGATIVE = "buttonNegative";
4747
/* package */ static final String KEY_BUTTON_NEUTRAL = "buttonNeutral";
4848
/* package */ static final String KEY_ITEMS = "items";
49+
/* package */ static final String KEY_CANCELABLE = "cancelable";
4950

5051
/* package */ static final Map<String, Object> CONSTANTS = MapBuilder.<String, Object>of(
5152
ACTION_BUTTON_CLICKED, ACTION_BUTTON_CLICKED,
@@ -129,13 +130,19 @@ public void showNewAlert(boolean isInForeground, Bundle arguments, Callback acti
129130
if (isUsingSupportLibrary()) {
130131
SupportAlertFragment alertFragment = new SupportAlertFragment(actionListener, arguments);
131132
if (isInForeground) {
133+
if (arguments.containsKey(KEY_CANCELABLE)) {
134+
alertFragment.setCancelable(arguments.getBoolean(KEY_CANCELABLE));
135+
}
132136
alertFragment.show(mSupportFragmentManager, FRAGMENT_TAG);
133137
} else {
134138
mFragmentToShow = alertFragment;
135139
}
136140
} else {
137141
AlertFragment alertFragment = new AlertFragment(actionListener, arguments);
138142
if (isInForeground) {
143+
if (arguments.containsKey(KEY_CANCELABLE)) {
144+
alertFragment.setCancelable(arguments.getBoolean(KEY_CANCELABLE));
145+
}
139146
alertFragment.show(mFragmentManager, FRAGMENT_TAG);
140147
} else {
141148
mFragmentToShow = alertFragment;
@@ -241,6 +248,9 @@ public void showAlert(
241248
}
242249
args.putCharSequenceArray(AlertFragment.ARG_ITEMS, itemsArray);
243250
}
251+
if (options.hasKey(KEY_CANCELABLE)) {
252+
args.putBoolean(KEY_CANCELABLE, options.getBoolean(KEY_CANCELABLE));
253+
}
244254

245255
fragmentManagerHelper.showNewAlert(mIsInForeground, args, actionCallback);
246256
}

ReactAndroid/src/test/java/com/facebook/react/modules/dialog/DialogModuleTest.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,11 +90,13 @@ public void testAllOptions() {
9090
options.putString("buttonPositive", "OK");
9191
options.putString("buttonNegative", "Cancel");
9292
options.putString("buttonNeutral", "Later");
93+
options.putBoolean("cancelable", false);
9394

9495
mDialogModule.showAlert(options, null, null);
9596

9697
final AlertFragment fragment = getFragment();
9798
assertNotNull("Fragment was not displayed", fragment);
99+
assertEquals(false, fragment.isCancelable());
98100

99101
final AlertDialog dialog = (AlertDialog) fragment.getDialog();
100102
assertEquals("OK", dialog.getButton(DialogInterface.BUTTON_POSITIVE).getText().toString());

0 commit comments

Comments
 (0)