mirror of
https://github.com/zhigang1992/react-native.git
synced 2026-03-26 07:04:05 +08:00
Open souce the Android Dialog module
Summary: public The `DialogModule` requires `android.support.v4.app.FragmentManager` which means every app that wants to use Dialogs would need to have its Activity extend the legacy `android.support.v4.app.FragmentActivity`. This diff makes the `DialogModule` work with both the Support `FragmentManager` (for AdsManager & potentially other fb apps) and the `android.app.FragmentManager` (for new apps with no legacy dependencies). Also wrap the native module in the same `Alert` API that we have on iOS and provide a cross-platform example. In my opinion the iOS Alert API is quite nice and easy to use. We still keep `AlertIOS` around because of its `prompt` function which is iOS-specific and also for backwards compatibility. Reviewed By: foghina Differential Revision: D2647000 fb-gh-sync-id: e2280451890bff58bd9c933ab53cd99055403858
This commit is contained in:
committed by
facebook-github-bot-5
parent
fe86771a22
commit
3a3af8a385
126
Libraries/Utilities/Alert.js
Normal file
126
Libraries/Utilities/Alert.js
Normal file
@@ -0,0 +1,126 @@
|
||||
/**
|
||||
* Copyright (c) 2015-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree. An additional grant
|
||||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*
|
||||
* @providesModule Alert
|
||||
* @flow
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
var AlertIOS = require('AlertIOS');
|
||||
var Platform = require('Platform');
|
||||
var DialogModuleAndroid = require('NativeModules').DialogManagerAndroid;
|
||||
|
||||
import type { AlertType, AlertButtonStyle } from 'AlertIOS';
|
||||
|
||||
type Buttons = Array<{
|
||||
text?: string;
|
||||
onPress?: ?Function;
|
||||
style?: AlertButtonStyle;
|
||||
}>;
|
||||
|
||||
/**
|
||||
* Launches an alert dialog with the specified title and message.
|
||||
*
|
||||
* Optionally provide a list of buttons. Tapping any button will fire the
|
||||
* respective onPress callback and dismiss the alert. By default, the only
|
||||
* button will be an 'OK' button.
|
||||
*
|
||||
* The last button in the list will be considered the 'Primary' button.
|
||||
*
|
||||
* ## iOS
|
||||
*
|
||||
* On iOS you can specify any number of buttons. Each button can optionally
|
||||
* specify a style and you can also specify type of the alert.
|
||||
* Refer to `AlertIOS` for details.
|
||||
*
|
||||
* ## Android
|
||||
*
|
||||
* On Android at most three buttons can be specified. Android has a concept
|
||||
* of a 'neutral', 'negative' and a 'positive' button:
|
||||
*
|
||||
* - If you specify one button, it will be the 'positive' one (such as 'OK')
|
||||
* - Two buttons mean 'negative', 'positive' (such as 'Cancel', 'OK')
|
||||
* - Three buttons mean 'neutral', 'negative', 'positive' (such as 'Later', 'Cancel', 'OK')
|
||||
*
|
||||
* ```
|
||||
* Alert.alert(
|
||||
* 'Alert Title',
|
||||
* 'My Alert Msg',
|
||||
* [
|
||||
* {text: 'Ask me later', onPress: () => console.log('Ask me later pressed')},
|
||||
* {text: 'Cancel', onPress: () => console.log('Cancel Pressed')},
|
||||
* {text: 'OK', onPress: () => console.log('OK Pressed')},
|
||||
* ]
|
||||
* )
|
||||
* ```
|
||||
*/
|
||||
class Alert {
|
||||
|
||||
static alert(
|
||||
title: ?string,
|
||||
message?: ?string,
|
||||
buttons?: Buttons,
|
||||
type?: AlertType
|
||||
): void {
|
||||
if (Platform.OS === 'ios') {
|
||||
AlertIOS.alert(title, message, buttons, type);
|
||||
} else if (Platform.OS === 'android') {
|
||||
AlertAndroid.alert(title, message, buttons);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrapper around the Android native module.
|
||||
*/
|
||||
class AlertAndroid {
|
||||
|
||||
static alert(
|
||||
title: ?string,
|
||||
message?: ?string,
|
||||
buttons?: Buttons,
|
||||
): void {
|
||||
var config = {
|
||||
title: title || '',
|
||||
message: message || '',
|
||||
};
|
||||
// At most three buttons (neutral, negative, positive). Ignore rest.
|
||||
// The text 'OK' should be probably localized. iOS Alert does that in native.
|
||||
var validButtons: Buttons = buttons ? buttons.slice(0, 3) : [{text: 'OK'}];
|
||||
var buttonPositive = validButtons.pop();
|
||||
var buttonNegative = validButtons.pop();
|
||||
var buttonNeutral = validButtons.pop();
|
||||
if (buttonNeutral) {
|
||||
config = {...config, buttonNeutral: buttonNeutral.text || '' }
|
||||
}
|
||||
if (buttonNegative) {
|
||||
config = {...config, buttonNegative: buttonNegative.text || '' }
|
||||
}
|
||||
if (buttonPositive) {
|
||||
config = {...config, buttonPositive: buttonPositive.text || '' }
|
||||
}
|
||||
DialogModuleAndroid.showAlert(
|
||||
config,
|
||||
(errorMessage) => console.warn(message),
|
||||
(action, buttonKey) => {
|
||||
if (action !== DialogModuleAndroid.buttonClicked) {
|
||||
return;
|
||||
}
|
||||
if (buttonKey === DialogModuleAndroid.buttonNeutral) {
|
||||
buttonNeutral.onPress && buttonNeutral.onPress();
|
||||
} else if (buttonKey === DialogModuleAndroid.buttonNegative) {
|
||||
buttonNegative.onPress && buttonNegative.onPress();
|
||||
} else if (buttonKey === DialogModuleAndroid.buttonPositive) {
|
||||
buttonPositive.onPress && buttonPositive.onPress();
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = Alert;
|
||||
@@ -14,14 +14,14 @@
|
||||
var RCTAlertManager = require('NativeModules').AlertManager;
|
||||
var invariant = require('invariant');
|
||||
|
||||
type AlertType = $Enum<{
|
||||
export type AlertType = $Enum<{
|
||||
'default': string;
|
||||
'plain-text': string;
|
||||
'secure-text': string;
|
||||
'login-password': string;
|
||||
}>;
|
||||
|
||||
type AlertButtonStyle = $Enum<{
|
||||
export type AlertButtonStyle = $Enum<{
|
||||
'default': string;
|
||||
'cancel': string;
|
||||
'destructive': string;
|
||||
@@ -32,20 +32,19 @@ type AlertButtonStyle = $Enum<{
|
||||
*
|
||||
* Optionally provide a list of buttons. Tapping any button will fire the
|
||||
* respective onPress callback and dismiss the alert. By default, the only
|
||||
* button will be an 'OK' button
|
||||
* button will be an 'OK' button.
|
||||
*
|
||||
* ```
|
||||
* AlertIOS.alert(
|
||||
* 'Foo Title',
|
||||
* 'My Alert Msg',
|
||||
* [
|
||||
* {text: 'OK', onPress: () => console.log('OK Pressed!')},
|
||||
* {text: 'Cancel', onPress: () => console.log('Cancel Pressed!'), style: 'cancel'},
|
||||
* {text: 'OK', onPress: () => console.log('OK Pressed')},
|
||||
* {text: 'Cancel', onPress: () => console.log('Cancel Pressed'), style: 'cancel'},
|
||||
* ]
|
||||
* )
|
||||
* ```
|
||||
*/
|
||||
|
||||
class AlertIOS {
|
||||
static alert(
|
||||
title: ?string,
|
||||
|
||||
1
Libraries/react-native/react-native.js
vendored
1
Libraries/react-native/react-native.js
vendored
@@ -51,6 +51,7 @@ var ReactNative = {
|
||||
// APIs
|
||||
get ActionSheetIOS() { return require('ActionSheetIOS'); },
|
||||
get AdSupportIOS() { return require('AdSupportIOS'); },
|
||||
get Alert() { return require('Alert'); },
|
||||
get AlertIOS() { return require('AlertIOS'); },
|
||||
get Animated() { return require('Animated'); },
|
||||
get AppRegistry() { return require('AppRegistry'); },
|
||||
|
||||
Reference in New Issue
Block a user