Android: Add onScroll event to TextInput
Summary: Corresponding iOS PR: https://github.com/facebook/react-native/pull/11002 This adds an onScroll event to TextInput which is useful when a multiline TextInput has so much content that it is scrollable. **Test plan (required)** Verified the event works properly in a test app. Also, my team uses this event in our app. Adam Comella Microsoft Corp. Closes https://github.com/facebook/react-native/pull/11001 Differential Revision: D4220941 Pulled By: mkonicek fbshipit-source-id: 7e420579946f2ae840c9e1fcdc8afab68007da17
This commit is contained in:
parent
eb4be7af38
commit
69e98cfc75
|
@ -739,6 +739,7 @@ const TextInput = React.createClass({
|
|||
children={children}
|
||||
disableFullscreenUI={this.props.disableFullscreenUI}
|
||||
textBreakStrategy={this.props.textBreakStrategy}
|
||||
onScroll={this._onScroll}
|
||||
/>;
|
||||
|
||||
return (
|
||||
|
|
|
@ -14,6 +14,7 @@ android_library(
|
|||
react_native_target('java/com/facebook/react/uimanager:uimanager'),
|
||||
react_native_target('java/com/facebook/react/uimanager/annotations:annotations'),
|
||||
react_native_target('java/com/facebook/react/views/imagehelper:imagehelper'),
|
||||
react_native_target('java/com/facebook/react/views/scroll:scroll'),
|
||||
react_native_target('java/com/facebook/react/views/text:text'),
|
||||
react_native_target('java/com/facebook/react/views/view:view'),
|
||||
],
|
||||
|
|
|
@ -80,6 +80,7 @@ public class ReactEditText extends EditText {
|
|||
private @Nullable String mReturnKeyType;
|
||||
private @Nullable SelectionWatcher mSelectionWatcher;
|
||||
private @Nullable ContentSizeWatcher mContentSizeWatcher;
|
||||
private @Nullable ScrollWatcher mScrollWatcher;
|
||||
private final InternalKeyListener mKeyListener;
|
||||
private boolean mDetectScrollMovement = false;
|
||||
|
||||
|
@ -106,6 +107,7 @@ public class ReactEditText extends EditText {
|
|||
mTextWatcherDelegator = null;
|
||||
mStagedInputType = getInputType();
|
||||
mKeyListener = new InternalKeyListener();
|
||||
mScrollWatcher = null;
|
||||
}
|
||||
|
||||
// After the text changes inside an EditText, TextView checks if a layout() has been requested.
|
||||
|
@ -171,6 +173,15 @@ public class ReactEditText extends EditText {
|
|||
return super.onKeyUp(keyCode, event);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onScrollChanged(int horiz, int vert, int oldHoriz, int oldVert) {
|
||||
super.onScrollChanged(horiz, vert, oldHoriz, oldVert);
|
||||
|
||||
if (mScrollWatcher != null) {
|
||||
mScrollWatcher.onScrollChanged(horiz, vert, oldHoriz, oldVert);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearFocus() {
|
||||
setFocusableInTouchMode(false);
|
||||
|
@ -220,6 +231,10 @@ public class ReactEditText extends EditText {
|
|||
mContentSizeWatcher = contentSizeWatcher;
|
||||
}
|
||||
|
||||
public void setScrollWatcher(ScrollWatcher scrollWatcher) {
|
||||
mScrollWatcher = scrollWatcher;
|
||||
}
|
||||
|
||||
@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.
|
||||
|
|
|
@ -48,6 +48,8 @@ import com.facebook.react.uimanager.annotations.ReactProp;
|
|||
import com.facebook.react.uimanager.annotations.ReactPropGroup;
|
||||
import com.facebook.react.uimanager.events.EventDispatcher;
|
||||
import com.facebook.react.views.imagehelper.ResourceDrawableIdHelper;
|
||||
import com.facebook.react.views.scroll.ScrollEvent;
|
||||
import com.facebook.react.views.scroll.ScrollEventType;
|
||||
import com.facebook.react.views.text.DefaultStyleValuesUtil;
|
||||
import com.facebook.react.views.text.ReactFontManager;
|
||||
import com.facebook.react.views.text.ReactTextUpdate;
|
||||
|
@ -278,6 +280,15 @@ public class ReactTextInputManager extends BaseViewManager<ReactEditText, Layout
|
|||
}
|
||||
}
|
||||
|
||||
@ReactProp(name = "onScroll", defaultBoolean = false)
|
||||
public void setOnScroll(final ReactEditText view, boolean onScroll) {
|
||||
if (onScroll) {
|
||||
view.setScrollWatcher(new ReactScrollWatcher(view));
|
||||
} else {
|
||||
view.setScrollWatcher(null);
|
||||
}
|
||||
}
|
||||
|
||||
@ReactProp(name = "placeholder")
|
||||
public void setPlaceholder(ReactEditText view, @Nullable String placeholder) {
|
||||
view.setHint(placeholder);
|
||||
|
@ -772,6 +783,41 @@ public class ReactTextInputManager extends BaseViewManager<ReactEditText, Layout
|
|||
}
|
||||
}
|
||||
|
||||
private class ReactScrollWatcher implements ScrollWatcher {
|
||||
|
||||
private ReactEditText mReactEditText;
|
||||
private EventDispatcher mEventDispatcher;
|
||||
private int mPreviousHoriz;
|
||||
private int mPreviousVert;
|
||||
|
||||
public ReactScrollWatcher(ReactEditText editText) {
|
||||
mReactEditText = editText;
|
||||
ReactContext reactContext = (ReactContext) editText.getContext();
|
||||
mEventDispatcher = reactContext.getNativeModule(UIManagerModule.class).getEventDispatcher();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onScrollChanged(int horiz, int vert, int oldHoriz, int oldVert) {
|
||||
if (mPreviousHoriz != horiz || mPreviousVert != vert) {
|
||||
ScrollEvent event = ScrollEvent.obtain(
|
||||
mReactEditText.getId(),
|
||||
ScrollEventType.SCROLL,
|
||||
horiz,
|
||||
vert,
|
||||
0, // can't get content width
|
||||
0, // can't get content height
|
||||
mReactEditText.getWidth(),
|
||||
mReactEditText.getHeight()
|
||||
);
|
||||
|
||||
mEventDispatcher.dispatchEvent(event);
|
||||
|
||||
mPreviousHoriz = horiz;
|
||||
mPreviousVert = vert;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable Map getExportedViewConstants() {
|
||||
return MapBuilder.of(
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
/**
|
||||
* Copyright (c) 2016-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;
|
||||
|
||||
public interface ScrollWatcher {
|
||||
public void onScrollChanged(int horiz, int vert, int oldHoriz, int oldVert);
|
||||
}
|
Loading…
Reference in New Issue