Add TextInput controlled selection prop on Android

Summary:
Android PR for TextInput selection, based on the iOS implementation in #8958.

** Test plan **
Tested using the text selection example in UIExplorer.
Closes https://github.com/facebook/react-native/pull/8962

Differential Revision: D3819285

Pulled By: andreicoman11

fbshipit-source-id: 9a2408af2a8b694258c88ab5c46322830c71452a
This commit is contained in:
Janic Duplessis
2016-09-05 07:04:26 -07:00
committed by Facebook Github Bot
parent 2ea65ec872
commit 3c1b69c1a9
6 changed files with 159 additions and 7 deletions

View File

@@ -64,6 +64,7 @@ public class ReactEditText extends EditText {
private int mDefaultGravityHorizontal;
private int mDefaultGravityVertical;
private int mNativeEventCount;
private int mMostRecentEventCount;
private @Nullable ArrayList<TextWatcher> mListeners;
private @Nullable TextWatcherDelegator mTextWatcherDelegator;
private int mStagedInputType;
@@ -86,6 +87,7 @@ public class ReactEditText extends EditText {
getGravity() & (Gravity.HORIZONTAL_GRAVITY_MASK | Gravity.RELATIVE_HORIZONTAL_GRAVITY_MASK);
mDefaultGravityVertical = getGravity() & Gravity.VERTICAL_GRAVITY_MASK;
mNativeEventCount = 0;
mMostRecentEventCount = 0;
mIsSettingTextFromJS = false;
mIsJSSettingFocus = false;
mBlurOnSubmit = true;
@@ -182,6 +184,16 @@ public class ReactEditText extends EditText {
mContentSizeWatcher = contentSizeWatcher;
}
@Override
public void setSelection(int start, int end) {
// Skip setting the selection if the text wasn't set because of an out of date value.
if (mMostRecentEventCount < mNativeEventCount) {
return;
}
super.setSelection(start, end);
}
@Override
protected void onSelectionChanged(int selStart, int selEnd) {
super.onSelectionChanged(selStart, selEnd);
@@ -265,7 +277,8 @@ public class ReactEditText extends EditText {
// VisibleForTesting from {@link TextInputEventsTestCase}.
public void maybeSetText(ReactTextUpdate reactTextUpdate) {
// Only set the text if it is up to date.
if (reactTextUpdate.getJsEventCounter() < mNativeEventCount) {
mMostRecentEventCount = reactTextUpdate.getJsEventCounter();
if (mMostRecentEventCount < mNativeEventCount) {
return;
}

View File

@@ -32,6 +32,7 @@ import com.facebook.infer.annotation.Assertions;
import com.facebook.react.bridge.JSApplicationIllegalArgumentException;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.bridge.ReadableArray;
import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.common.MapBuilder;
import com.facebook.react.uimanager.BaseViewManager;
import com.facebook.react.uimanager.LayoutShadowNode;
@@ -230,6 +231,17 @@ public class ReactTextInputManager extends BaseViewManager<ReactEditText, Layout
}
}
@ReactProp(name = "selection")
public void setSelection(ReactEditText view, @Nullable ReadableMap selection) {
if (selection == null) {
return;
}
if (selection.hasKey("start") && selection.hasKey("end")) {
view.setSelection(selection.getInt("start"), selection.getInt("end"));
}
}
@ReactProp(name = "onSelectionChange", defaultBoolean = false)
public void setOnSelectionChange(final ReactEditText view, boolean onSelectionChange) {
if (onSelectionChange) {

View File

@@ -48,8 +48,8 @@ import com.facebook.react.uimanager.events.RCTEventEmitter;
WritableMap eventData = Arguments.createMap();
WritableMap selectionData = Arguments.createMap();
selectionData.putInt("start", mSelectionStart);
selectionData.putInt("end", mSelectionEnd);
selectionData.putInt("start", mSelectionStart);
eventData.putMap("selection", selectionData);
return eventData;