Skip to content

Commit 372d001

Browse files
andreicoman11Facebook Github Bot 0
authored andcommitted
Smart textinput scroll
Summary: This diff changes the textinput component to only scroll (and interrupt parent views from scrolling), when it is possible for the text inside the component to be scrolled. Before (D3735237), we would intercept all touch events on the textinput if it's focused. But this makes it: a.) impossible to scroll a scrollview from within a textinput that cannot be scrolled; b.) different from iOS behavior. What the component now does is intercept move touches, and check if it can scroll in any direction. If it does, it will intercept the touches and stop the parent component from scrolling; otherwise, it will give the control back to the parent component. Note: this might change in the future to also detect the direction of the scroll, and only block the scroll if the component can scroll in that direction. This is however not trivial, since the scroll needs to be above some threshold of pixels. Blocking the parent view from scrolling until that threshold is passed might cause incorrect behavior in the parent component. Reviewed By: astreet Differential Revision: D3764267 fbshipit-source-id: 47e7b5e03855b3c85789e04fc31a8317afbafa84
1 parent 3efe95d commit 372d001

File tree

1 file changed

+28
-8
lines changed

1 file changed

+28
-8
lines changed

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

Lines changed: 28 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@
1515

1616
import android.content.Context;
1717
import android.graphics.Rect;
18-
import android.graphics.drawable.Drawable;
1918
import android.graphics.Typeface;
19+
import android.graphics.drawable.Drawable;
2020
import android.text.Editable;
2121
import android.text.InputType;
2222
import android.text.SpannableStringBuilder;
@@ -29,6 +29,7 @@
2929
import android.text.style.ForegroundColorSpan;
3030
import android.view.Gravity;
3131
import android.view.KeyEvent;
32+
import android.view.MotionEvent;
3233
import android.view.View;
3334
import android.view.inputmethod.InputMethodManager;
3435
import android.widget.EditText;
@@ -68,12 +69,12 @@ public class ReactEditText extends EditText {
6869
private @Nullable ArrayList<TextWatcher> mListeners;
6970
private @Nullable TextWatcherDelegator mTextWatcherDelegator;
7071
private int mStagedInputType;
71-
private boolean mTextIsSelectable = true;
7272
private boolean mContainsImages;
7373
private boolean mBlurOnSubmit;
7474
private @Nullable SelectionWatcher mSelectionWatcher;
7575
private @Nullable ContentSizeWatcher mContentSizeWatcher;
7676
private final InternalKeyListener mKeyListener;
77+
private boolean mDetectScrollMovement = false;
7778

7879
private static final KeyListener sKeyListener = QwertyKeyListener.getInstanceForFullKeyboard();
7980

@@ -124,6 +125,31 @@ protected void onLayout(boolean changed, int left, int top, int right, int botto
124125
}
125126
}
126127

128+
@Override
129+
public boolean onTouchEvent(MotionEvent ev) {
130+
switch (ev.getAction()) {
131+
case MotionEvent.ACTION_DOWN:
132+
mDetectScrollMovement = true;
133+
// Disallow parent views to intercept touch events, until we can detect if we should be
134+
// capturing these touches or not.
135+
this.getParent().requestDisallowInterceptTouchEvent(true);
136+
break;
137+
case MotionEvent.ACTION_MOVE:
138+
if (mDetectScrollMovement) {
139+
if (!canScrollVertically(-1) &&
140+
!canScrollVertically(1) &&
141+
!canScrollHorizontally(-1) &&
142+
!canScrollHorizontally(1)) {
143+
// We cannot scroll, let parent views take care of these touches.
144+
this.getParent().requestDisallowInterceptTouchEvent(false);
145+
}
146+
mDetectScrollMovement = false;
147+
}
148+
break;
149+
}
150+
return super.onTouchEvent(ev);
151+
}
152+
127153
// Consume 'Enter' key events: TextView tries to give focus to the next TextInput, but it can't
128154
// since we only allow JS to change focus, which in turn causes TextView to crash.
129155
@Override
@@ -252,12 +278,6 @@ public void setInputType(int type) {
252278
setKeyListener(mKeyListener);
253279
}
254280

255-
@Override
256-
public void setTextIsSelectable(boolean selectable) {
257-
mTextIsSelectable = selectable;
258-
super.setTextIsSelectable(selectable);
259-
}
260-
261281
// VisibleForTesting from {@link TextInputEventsTestCase}.
262282
public void requestFocusFromJS() {
263283
mIsJSSettingFocus = true;

0 commit comments

Comments
 (0)