mirror of
https://github.com/zhigang1992/react-native.git
synced 2026-02-10 09:12:46 +08:00
Add onSelectionChange for Android TextInput
Summary: public Add an onSelectionChange method to TextInput that works on Android same as iOS Reviewed By: andreicoman11 Differential Revision: D2780131 fb-gh-sync-id: 9b3b8fbd9ea653d43e3107a338e4bc08bde2e8c6
This commit is contained in:
committed by
facebook-github-bot-3
parent
857dd59340
commit
6dc6794881
@@ -64,6 +64,7 @@ public class ReactEditText extends EditText {
|
||||
private @Nullable TextWatcherDelegator mTextWatcherDelegator;
|
||||
private int mStagedInputType;
|
||||
private boolean mContainsImages;
|
||||
private @Nullable SelectionWatcher mSelectionWatcher;
|
||||
|
||||
public ReactEditText(Context context) {
|
||||
super(context);
|
||||
@@ -150,6 +151,27 @@ public class ReactEditText extends EditText {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onSelectionChanged(int selStart, int selEnd) {
|
||||
super.onSelectionChanged(selStart, selEnd);
|
||||
if (mSelectionWatcher != null && hasFocus()) {
|
||||
mSelectionWatcher.onSelectionChanged(selStart, selEnd);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onFocusChanged(
|
||||
boolean focused, int direction, Rect previouslyFocusedRect) {
|
||||
super.onFocusChanged(focused, direction, previouslyFocusedRect);
|
||||
if (focused && mSelectionWatcher != null) {
|
||||
mSelectionWatcher.onSelectionChanged(getSelectionStart(), getSelectionEnd());
|
||||
}
|
||||
}
|
||||
|
||||
public void setSelectionWatcher(SelectionWatcher selectionWatcher) {
|
||||
mSelectionWatcher = selectionWatcher;
|
||||
}
|
||||
|
||||
/*protected*/ int getStagedInputType() {
|
||||
return mStagedInputType;
|
||||
}
|
||||
@@ -170,7 +192,8 @@ public class ReactEditText extends EditText {
|
||||
mStagedInputType = type;
|
||||
}
|
||||
|
||||
/* package */ void requestFocusFromJS() {
|
||||
// VisibleForTesting from {@link TextInputEventsTestCase}.
|
||||
public void requestFocusFromJS() {
|
||||
mIsJSSettingFocus = true;
|
||||
requestFocus();
|
||||
mIsJSSettingFocus = false;
|
||||
|
||||
@@ -166,6 +166,15 @@ public class ReactTextInputManager extends
|
||||
(int) Math.ceil(PixelUtil.toPixelFromSP(fontSize)));
|
||||
}
|
||||
|
||||
@ReactProp(name = "onSelectionChange", defaultBoolean = false)
|
||||
public void setOnSelectionChange(final ReactEditText view, boolean onSelectionChange) {
|
||||
if (onSelectionChange) {
|
||||
view.setSelectionWatcher(new ReactSelectionWatcher(view));
|
||||
} else {
|
||||
view.setSelectionWatcher(null);
|
||||
}
|
||||
}
|
||||
|
||||
@ReactProp(name = "placeholder")
|
||||
public void setPlaceholder(ReactEditText view, @Nullable String placeholder) {
|
||||
view.setHint(placeholder);
|
||||
@@ -418,6 +427,40 @@ public class ReactTextInputManager extends
|
||||
});
|
||||
}
|
||||
|
||||
private class ReactSelectionWatcher implements SelectionWatcher {
|
||||
|
||||
private ReactEditText mReactEditText;
|
||||
private EventDispatcher mEventDispatcher;
|
||||
private int mPreviousSelectionStart;
|
||||
private int mPreviousSelectionEnd;
|
||||
|
||||
public ReactSelectionWatcher(ReactEditText editText) {
|
||||
mReactEditText = editText;
|
||||
ReactContext reactContext = (ReactContext) editText.getContext();
|
||||
mEventDispatcher = reactContext.getNativeModule(UIManagerModule.class).getEventDispatcher();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSelectionChanged(int start, int end) {
|
||||
// Android will call us back for both the SELECTION_START span and SELECTION_END span in text
|
||||
// To prevent double calling back into js we cache the result of the previous call and only
|
||||
// forward it on if we have new values
|
||||
if (mPreviousSelectionStart != start || mPreviousSelectionEnd != end) {
|
||||
mEventDispatcher.dispatchEvent(
|
||||
new ReactTextInputSelectionEvent(
|
||||
mReactEditText.getId(),
|
||||
SystemClock.uptimeMillis(),
|
||||
start,
|
||||
end
|
||||
)
|
||||
);
|
||||
|
||||
mPreviousSelectionStart = start;
|
||||
mPreviousSelectionEnd = end;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable Map getExportedViewConstants() {
|
||||
return MapBuilder.of(
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package com.facebook.react.views.textinput;
|
||||
|
||||
import com.facebook.react.bridge.Arguments;
|
||||
import com.facebook.react.bridge.WritableMap;
|
||||
import com.facebook.react.uimanager.events.Event;
|
||||
import com.facebook.react.uimanager.events.RCTEventEmitter;
|
||||
|
||||
/**
|
||||
* Event emitted by EditText native view when the text selection changes.
|
||||
*/
|
||||
/* package */ class ReactTextInputSelectionEvent
|
||||
extends Event<ReactTextInputSelectionEvent> {
|
||||
|
||||
private static final String EVENT_NAME = "topSelectionChange";
|
||||
|
||||
private int mSelectionStart;
|
||||
private int mSelectionEnd;
|
||||
|
||||
public ReactTextInputSelectionEvent(
|
||||
int viewId,
|
||||
long timestampMs,
|
||||
int selectionStart,
|
||||
int selectionEnd) {
|
||||
super(viewId, timestampMs);
|
||||
mSelectionStart = selectionStart;
|
||||
mSelectionEnd = selectionEnd;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getEventName() {
|
||||
return EVENT_NAME;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispatch(RCTEventEmitter rctEventEmitter) {
|
||||
rctEventEmitter.receiveEvent(getViewTag(), getEventName(), serializeEventData());
|
||||
}
|
||||
|
||||
private WritableMap serializeEventData() {
|
||||
WritableMap eventData = Arguments.createMap();
|
||||
|
||||
WritableMap selectionData = Arguments.createMap();
|
||||
selectionData.putInt("start", mSelectionStart);
|
||||
selectionData.putInt("end", mSelectionEnd);
|
||||
|
||||
eventData.putMap("selection", selectionData);
|
||||
return eventData;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package com.facebook.react.views.textinput;
|
||||
|
||||
/**
|
||||
* Implement this interface to be informed of selection changes in the ReactTextEdit
|
||||
* This is used by the ReactTextInputManager to forward events from the EditText to JS
|
||||
*/
|
||||
interface SelectionWatcher {
|
||||
public void onSelectionChanged(int start, int end);
|
||||
}
|
||||
Reference in New Issue
Block a user