diff --git a/Libraries/Components/Keyboard/Keyboard.js b/Libraries/Components/Keyboard/Keyboard.js index 4e5674fb984..a7970fc8ed0 100644 --- a/Libraries/Components/Keyboard/Keyboard.js +++ b/Libraries/Components/Keyboard/Keyboard.js @@ -33,18 +33,29 @@ export type KeyboardEventEasing = | 'linear' | 'keyboard'; -type ScreenRect = $ReadOnly<{| +export type KeyboardEventCoordinates = $ReadOnly<{| screenX: number, screenY: number, width: number, height: number, |}>; -export type KeyboardEvent = $ReadOnly<{| +export type KeyboardEvent = AndroidKeyboardEvent | IOSKeyboardEvent; + +type BaseKeyboardEvent = {| duration: number, easing: KeyboardEventEasing, - endCoordinates: ScreenRect, - startCoordinates: ScreenRect, + endCoordinates: KeyboardEventCoordinates, +|}; + +export type AndroidKeyboardEvent = $ReadOnly<{| + ...BaseKeyboardEvent, + easing: 'keyboard', +|}>; + +export type IOSKeyboardEvent = $ReadOnly<{| + ...BaseKeyboardEvent, + startCoordinates: KeyboardEventCoordinates, isEventFromThisApp: boolean, |}>; diff --git a/RNTester/js/RNTesterList.android.js b/RNTester/js/RNTesterList.android.js index a721932ddff..7d2677f137a 100644 --- a/RNTester/js/RNTesterList.android.js +++ b/RNTester/js/RNTesterList.android.js @@ -33,6 +33,10 @@ const ComponentExamples: Array = [ key: 'ImageExample', module: require('./ImageExample'), }, + { + key: 'KeyboardAvoidingViewExample', + module: require('./KeyboardAvoidingViewExample'), + }, { key: 'ModalExample', module: require('./ModalExample'), diff --git a/ReactAndroid/src/main/java/com/facebook/react/ReactRootView.java b/ReactAndroid/src/main/java/com/facebook/react/ReactRootView.java index 97b594049a3..42d2c757ef2 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/ReactRootView.java +++ b/ReactAndroid/src/main/java/com/facebook/react/ReactRootView.java @@ -648,21 +648,33 @@ public class ReactRootView extends FrameLayout implements RootView, ReactRoot { getRootView().getWindowVisibleDisplayFrame(mVisibleViewArea); final int heightDiff = DisplayMetricsHolder.getWindowDisplayMetrics().heightPixels - mVisibleViewArea.bottom; - if (mKeyboardHeight != heightDiff && heightDiff > mMinKeyboardHeightDetected) { - // keyboard is now showing, or the keyboard height has changed + + boolean isKeyboardShowingOrKeyboardHeightChanged = + mKeyboardHeight != heightDiff && heightDiff > mMinKeyboardHeightDetected; + if (isKeyboardShowingOrKeyboardHeightChanged) { mKeyboardHeight = heightDiff; - WritableMap params = Arguments.createMap(); - WritableMap coordinates = Arguments.createMap(); - coordinates.putDouble("screenY", PixelUtil.toDIPFromPixel(mVisibleViewArea.bottom)); - coordinates.putDouble("screenX", PixelUtil.toDIPFromPixel(mVisibleViewArea.left)); - coordinates.putDouble("width", PixelUtil.toDIPFromPixel(mVisibleViewArea.width())); - coordinates.putDouble("height", PixelUtil.toDIPFromPixel(mKeyboardHeight)); - params.putMap("endCoordinates", coordinates); - sendEvent("keyboardDidShow", params); - } else if (mKeyboardHeight != 0 && heightDiff <= mMinKeyboardHeightDetected) { - // keyboard is now hidden + sendEvent("keyboardDidShow", + createKeyboardEventPayload( + PixelUtil.toDIPFromPixel(mVisibleViewArea.bottom), + PixelUtil.toDIPFromPixel(mVisibleViewArea.left), + PixelUtil.toDIPFromPixel(mVisibleViewArea.width()), + PixelUtil.toDIPFromPixel(mKeyboardHeight)) + ); + return; + } + + boolean isKeyboardHidden = + mKeyboardHeight != 0 && heightDiff <= mMinKeyboardHeightDetected; + if (isKeyboardHidden) { mKeyboardHeight = 0; - sendEvent("keyboardDidHide", null); + sendEvent("keyboardDidHide", + createKeyboardEventPayload( + PixelUtil.toDIPFromPixel(mVisibleViewArea.height()), + 0, + PixelUtil.toDIPFromPixel(mVisibleViewArea.width()), + 0 + ) + ); } } @@ -746,5 +758,19 @@ public class ReactRootView extends FrameLayout implements RootView, ReactRoot { .getNativeModule(DeviceInfoModule.class) .emitUpdateDimensionsEvent(); } + + private WritableMap createKeyboardEventPayload(double screenY, double screenX, double width, double height) { + WritableMap keyboardEventParams = Arguments.createMap(); + WritableMap endCoordinates = Arguments.createMap(); + + endCoordinates.putDouble("height", height); + endCoordinates.putDouble("screenX", screenX); + endCoordinates.putDouble("width", width); + endCoordinates.putDouble("screenY", screenY); + + keyboardEventParams.putMap("endCoordinates", endCoordinates); + keyboardEventParams.putString("easing", "keyboard"); + return keyboardEventParams; + } } }