mirror of
https://github.com/zhigang1992/react-native.git
synced 2026-04-30 22:12:42 +08:00
TextInput: Avoid firing onSubmitEditing twice on Android
Summary: For returnKeyType 'go', 'search' and 'send' Android will call onEditorAction twice, once with IME_NULL and another time with the respective IME_ACTION. This change makes sure to only fire one onSubmitEditing by always returning true in onEditorAction, which causes no subsequent events to be fired by android. Fixes #10443 **Test plan** 1. Create view with TextInput having 'go', 'search' or 'send as `returnKeyType` ```javascript <View> <TextInput returnKeyType='search' onSubmitEditing={event => console.log('submit search')}></TextInput> <TextInput returnKeyType='go' onSubmitEditing={event => console.log('submit go')}></TextInput> <TextInput returnKeyType='send' onSubmitEditing={event => console.log('submit send')}></TextInput> </View> ``` 2. Input some text and click submit button in soft keyboard 3. See event fired only once instead of two times Closes https://github.com/facebook/react-native/pull/11006 Differential Revision: D4439110 Pulled By: hramos fbshipit-source-id: 5573b7f15f862b432600ddd3d61a0852ce51b2b3
This commit is contained in:
committed by
Facebook Github Bot
parent
f521e992cc
commit
116916b98d
@@ -11,25 +11,26 @@ package com.facebook.react.tests;
|
||||
import android.graphics.Color;
|
||||
import android.text.style.ForegroundColorSpan;
|
||||
import android.util.TypedValue;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.inputmethod.EditorInfo;
|
||||
import android.widget.EditText;
|
||||
|
||||
import com.facebook.react.bridge.JavaScriptModule;
|
||||
import com.facebook.react.testing.ReactAppInstrumentationTestCase;
|
||||
import com.facebook.react.testing.ReactInstanceSpecForTest;
|
||||
import com.facebook.react.testing.StringRecordingModule;
|
||||
import com.facebook.react.uimanager.PixelUtil;
|
||||
import com.facebook.react.uimanager.UIManagerModule;
|
||||
import com.facebook.react.uimanager.events.EventDispatcher;
|
||||
import com.facebook.react.views.textinput.ReactEditText;
|
||||
import com.facebook.react.views.textinput.ReactTextChangedEvent;
|
||||
import com.facebook.react.views.textinput.ReactTextInputEvent;
|
||||
|
||||
/**
|
||||
* Test to verify that TextInput renders correctly
|
||||
*/
|
||||
public class TextInputTestCase extends ReactAppInstrumentationTestCase {
|
||||
|
||||
private final StringRecordingModule mRecordingModule = new StringRecordingModule();
|
||||
|
||||
private interface TextInputTestModule extends JavaScriptModule {
|
||||
void setValueRef(String ref, String value);
|
||||
}
|
||||
@@ -99,6 +100,46 @@ public class TextInputTestCase extends ReactAppInstrumentationTestCase {
|
||||
}
|
||||
}
|
||||
|
||||
public void testOnSubmitEditing() throws Throwable {
|
||||
String testId = "onSubmitTextInput";
|
||||
ReactEditText reactEditText = getViewByTestId(testId);
|
||||
|
||||
fireEditorActionAndCheckRecording(reactEditText, EditorInfo.IME_ACTION_GO);
|
||||
fireEditorActionAndCheckRecording(reactEditText, EditorInfo.IME_ACTION_DONE);
|
||||
fireEditorActionAndCheckRecording(reactEditText, EditorInfo.IME_ACTION_NEXT);
|
||||
fireEditorActionAndCheckRecording(reactEditText, EditorInfo.IME_ACTION_PREVIOUS);
|
||||
fireEditorActionAndCheckRecording(reactEditText, EditorInfo.IME_ACTION_SEARCH);
|
||||
fireEditorActionAndCheckRecording(reactEditText, EditorInfo.IME_ACTION_SEND);
|
||||
fireEditorActionAndCheckRecording(reactEditText, EditorInfo.IME_ACTION_UNSPECIFIED);
|
||||
fireEditorActionAndCheckRecording(reactEditText, EditorInfo.IME_ACTION_NONE);
|
||||
}
|
||||
|
||||
private void fireEditorActionAndCheckRecording(final ReactEditText reactEditText,
|
||||
final int actionId) throws Throwable {
|
||||
fireEditorActionAndCheckRecording(reactEditText, actionId, true);
|
||||
fireEditorActionAndCheckRecording(reactEditText, actionId, false);
|
||||
}
|
||||
|
||||
private void fireEditorActionAndCheckRecording(final ReactEditText reactEditText,
|
||||
final int actionId,
|
||||
final boolean blurOnSubmit) throws Throwable {
|
||||
mRecordingModule.reset();
|
||||
|
||||
runTestOnUiThread(
|
||||
new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
reactEditText.requestFocusFromJS();
|
||||
reactEditText.setBlurOnSubmit(blurOnSubmit);
|
||||
reactEditText.onEditorAction(actionId);
|
||||
}
|
||||
});
|
||||
waitForBridgeAndUIIdle();
|
||||
|
||||
assertEquals(1, mRecordingModule.getCalls().size());
|
||||
assertEquals(!blurOnSubmit, reactEditText.isFocused());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that the mentions input has colors displayed correctly.
|
||||
* Removed for being flaky in open source, December 2016
|
||||
@@ -207,7 +248,8 @@ public class TextInputTestCase extends ReactAppInstrumentationTestCase {
|
||||
@Override
|
||||
protected ReactInstanceSpecForTest createReactInstanceSpecForTest() {
|
||||
return super.createReactInstanceSpecForTest()
|
||||
.addJSModule(TextInputTestModule.class);
|
||||
.addJSModule(TextInputTestModule.class)
|
||||
.addNativeModule(mRecordingModule);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -18,6 +18,8 @@ var Text = require('Text');
|
||||
var TextInput = require('TextInput');
|
||||
var View = require('View');
|
||||
|
||||
var Recording = require('NativeModules').Recording;
|
||||
|
||||
var app;
|
||||
|
||||
class TokenizedTextExample extends React.Component {
|
||||
@@ -81,6 +83,10 @@ class TextInputTestApp extends React.Component {
|
||||
app = this;
|
||||
}
|
||||
|
||||
handleOnSubmitEditing = (record) => {
|
||||
Recording.record(record);
|
||||
};
|
||||
|
||||
render() {
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
@@ -128,6 +134,12 @@ class TextInputTestApp extends React.Component {
|
||||
defaultValue="Text"
|
||||
testID="textInput6"
|
||||
/>
|
||||
<TextInput
|
||||
ref="onSubmitTextInput"
|
||||
onSubmitEditing={this.handleOnSubmitEditing.bind(this, 'onSubmit')}
|
||||
defaultValue=""
|
||||
testID="onSubmitTextInput"
|
||||
/>
|
||||
<TokenizedTextExample />
|
||||
</View>
|
||||
);
|
||||
|
||||
@@ -688,14 +688,12 @@ public class ReactTextInputManager extends BaseViewManager<ReactEditText, Layout
|
||||
editText.getId(),
|
||||
editText.getText().toString()));
|
||||
}
|
||||
if (actionId == EditorInfo.IME_ACTION_NEXT ||
|
||||
actionId == EditorInfo.IME_ACTION_PREVIOUS) {
|
||||
if (editText.getBlurOnSubmit()) {
|
||||
editText.clearFocus();
|
||||
}
|
||||
return true;
|
||||
|
||||
if (editText.getBlurOnSubmit()) {
|
||||
editText.clearFocus();
|
||||
}
|
||||
return !editText.getBlurOnSubmit();
|
||||
|
||||
return true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user