Skip to content

Commit 1b870d2

Browse files
Adam ComellaFacebook Github Bot
Adam Comella
authored and
Facebook Github Bot
committed
Android: Add disableExtractUI prop to TextInput on Android
Summary: On Android, if there is a small amount of space available around a text input (e.g. landscape orientation on a phone), Android may choose to have the user edit the text inside of a full screen text input mode. This behavior isn't always desirable. For example, if your app offers some UI controls for controlling the formatting of the text, you want the controls to be visible while the user is editing the text. This Android feature conflicts with that desired experience because the UI controls would be hidden while the text is being edited. The `disableExtractUI` prop enables developers to choose whether or not Android's full screen text input editing mode is enabled. When this prop is true, Android's `IME_FLAG_NO_EXTRACT_UI` flag is passed to the `setImeOptions` method. **Test plan (required)** Verified `disableExtractUI` works for both `true` and `false` values in a test app. My team is also using this change in our app. Adam Comella Microsoft Corp. Closes #10900 Differential Revision: D4226483 Pulled By: mkonicek fbshipit-source-id: 8f1055f6e612b05bafabe6f07a3705dd8788e3da
1 parent 9fb520e commit 1b870d2

File tree

3 files changed

+75
-24
lines changed

3 files changed

+75
-24
lines changed

Libraries/Components/TextInput/TextInput.js

+10
Original file line numberDiff line numberDiff line change
@@ -304,6 +304,15 @@ const TextInput = React.createClass({
304304
* @platform android
305305
*/
306306
numberOfLines: PropTypes.number,
307+
/**
308+
* When `false`, if there is a small amount of space available around a text input
309+
* (e.g. landscape orientation on a phone), the OS may choose to have the user edit
310+
* the text inside of a full screen text input mode. When `true`, this feature is
311+
* disabled and users will always edit the text directly inside of the text input.
312+
* Defaults to `false`.
313+
* @platform android
314+
*/
315+
disableFullscreenUI: PropTypes.bool,
307316
/**
308317
* If `true`, the keyboard disables the return key when there is no text and
309318
* automatically enables it when there is text. The default value is `false`.
@@ -708,6 +717,7 @@ const TextInput = React.createClass({
708717
onTextInput={this._onTextInput}
709718
text={this._getText()}
710719
children={children}
720+
disableFullscreenUI={this.props.disableFullscreenUI}
711721
/>;
712722

713723
return (

ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactEditText.java

+58
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
import android.view.KeyEvent;
3434
import android.view.MotionEvent;
3535
import android.view.View;
36+
import android.view.inputmethod.EditorInfo;
3637
import android.view.inputmethod.InputMethodManager;
3738
import android.widget.EditText;
3839

@@ -74,6 +75,8 @@ public class ReactEditText extends EditText {
7475
private int mStagedInputType;
7576
private boolean mContainsImages;
7677
private boolean mBlurOnSubmit;
78+
private boolean mDisableFullscreen;
79+
private @Nullable String mReturnKeyType;
7780
private @Nullable SelectionWatcher mSelectionWatcher;
7881
private @Nullable ContentSizeWatcher mContentSizeWatcher;
7982
private final InternalKeyListener mKeyListener;
@@ -97,6 +100,7 @@ public ReactEditText(Context context) {
97100
mIsSettingTextFromJS = false;
98101
mIsJSSettingFocus = false;
99102
mBlurOnSubmit = true;
103+
mDisableFullscreen = false;
100104
mListeners = null;
101105
mTextWatcherDelegator = null;
102106
mStagedInputType = getInputType();
@@ -254,6 +258,24 @@ public boolean getBlurOnSubmit() {
254258
return mBlurOnSubmit;
255259
}
256260

261+
public void setDisableFullscreenUI(boolean disableFullscreenUI) {
262+
mDisableFullscreen = disableFullscreenUI;
263+
updateImeOptions();
264+
}
265+
266+
public boolean getDisableFullscreenUI() {
267+
return mDisableFullscreen;
268+
}
269+
270+
public void setReturnKeyType(String returnKeyType) {
271+
mReturnKeyType = returnKeyType;
272+
updateImeOptions();
273+
}
274+
275+
public String getReturnKeyType() {
276+
return mReturnKeyType;
277+
}
278+
257279
/*protected*/ int getStagedInputType() {
258280
return mStagedInputType;
259281
}
@@ -407,6 +429,42 @@ private boolean isMultiline() {
407429
setGravity((getGravity() & ~Gravity.VERTICAL_GRAVITY_MASK) | gravityVertical);
408430
}
409431

432+
private void updateImeOptions() {
433+
// Default to IME_ACTION_DONE
434+
int returnKeyFlag = EditorInfo.IME_ACTION_DONE;
435+
if (mReturnKeyType != null) {
436+
switch (mReturnKeyType) {
437+
case "go":
438+
returnKeyFlag = EditorInfo.IME_ACTION_GO;
439+
break;
440+
case "next":
441+
returnKeyFlag = EditorInfo.IME_ACTION_NEXT;
442+
break;
443+
case "none":
444+
returnKeyFlag = EditorInfo.IME_ACTION_NONE;
445+
break;
446+
case "previous":
447+
returnKeyFlag = EditorInfo.IME_ACTION_PREVIOUS;
448+
break;
449+
case "search":
450+
returnKeyFlag = EditorInfo.IME_ACTION_SEARCH;
451+
break;
452+
case "send":
453+
returnKeyFlag = EditorInfo.IME_ACTION_SEND;
454+
break;
455+
case "done":
456+
returnKeyFlag = EditorInfo.IME_ACTION_DONE;
457+
break;
458+
}
459+
}
460+
461+
if (mDisableFullscreen) {
462+
setImeOptions(returnKeyFlag | EditorInfo.IME_FLAG_NO_FULLSCREEN);
463+
} else {
464+
setImeOptions(returnKeyFlag);
465+
}
466+
}
467+
410468
@Override
411469
protected boolean verifyDrawable(Drawable drawable) {
412470
if (mContainsImages && getText() instanceof Spanned) {

ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactTextInputManager.java

+7-24
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ public ReactEditText createViewInstance(ThemedReactContext context) {
8888
ReactEditText editText = new ReactEditText(context);
8989
int inputType = editText.getInputType();
9090
editText.setInputType(inputType & (~InputType.TYPE_TEXT_FLAG_MULTI_LINE));
91-
editText.setImeOptions(EditorInfo.IME_ACTION_DONE);
91+
editText.setReturnKeyType("done");
9292
editText.setTextSize(
9393
TypedValue.COMPLEX_UNIT_PX,
9494
(int) Math.ceil(PixelUtil.toPixelFromSP(ViewDefaults.FONT_SIZE_SP)));
@@ -475,29 +475,12 @@ public void setKeyboardType(ReactEditText view, @Nullable String keyboardType) {
475475

476476
@ReactProp(name = "returnKeyType")
477477
public void setReturnKeyType(ReactEditText view, String returnKeyType) {
478-
switch (returnKeyType) {
479-
case "done":
480-
view.setImeOptions(EditorInfo.IME_ACTION_DONE);
481-
break;
482-
case "go":
483-
view.setImeOptions(EditorInfo.IME_ACTION_GO);
484-
break;
485-
case "next":
486-
view.setImeOptions(EditorInfo.IME_ACTION_NEXT);
487-
break;
488-
case "none":
489-
view.setImeOptions(EditorInfo.IME_ACTION_NONE);
490-
break;
491-
case "previous":
492-
view.setImeOptions(EditorInfo.IME_ACTION_PREVIOUS);
493-
break;
494-
case "search":
495-
view.setImeOptions(EditorInfo.IME_ACTION_SEARCH);
496-
break;
497-
case "send":
498-
view.setImeOptions(EditorInfo.IME_ACTION_SEND);
499-
break;
500-
}
478+
view.setReturnKeyType(returnKeyType);
479+
}
480+
481+
@ReactProp(name = "disableFullscreenUI", defaultBoolean = false)
482+
public void setDisableFullscreenUI(ReactEditText view, boolean disableFullscreenUI) {
483+
view.setDisableFullscreenUI(disableFullscreenUI);
501484
}
502485

503486
private static final int IME_ACTION_ID = 0x670;

0 commit comments

Comments
 (0)