Skip to content

Commit c171402

Browse files
author
Gilles Debunne
committed
Touch slop added to double tap detection
Similar to what is done in GestureDetector Removed all gesture constants. Only one one them is used on MOVE (added an early exit test), the 2 others on UP or DOWN where performance is not such an issue. Change-Id: Icd58ead5078f94f86786f934ddf81aa5ec9bf549
1 parent b2d81fe commit c171402

File tree

1 file changed

+50
-28
lines changed

1 file changed

+50
-28
lines changed

core/java/android/widget/TextView.java

Lines changed: 50 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -357,7 +357,6 @@ static class InputMethodState {
357357
private float mLastDownPositionX, mLastDownPositionY;
358358
private Callback mCustomSelectionActionModeCallback;
359359

360-
private final int mSquaredTouchSlopDistance;
361360
// Set when this TextView gained focus with some text selected. Will start selection mode.
362361
private boolean mCreatedWithASelection = false;
363362

@@ -443,15 +442,12 @@ public TextView(Context context) {
443442
this(context, null);
444443
}
445444

446-
public TextView(Context context,
447-
AttributeSet attrs) {
445+
public TextView(Context context, AttributeSet attrs) {
448446
this(context, attrs, com.android.internal.R.attr.textViewStyle);
449447
}
450448

451449
@SuppressWarnings("deprecation")
452-
public TextView(Context context,
453-
AttributeSet attrs,
454-
int defStyle) {
450+
public TextView(Context context, AttributeSet attrs, int defStyle) {
455451
super(context, attrs, defStyle);
456452
mText = "";
457453

@@ -1134,10 +1130,6 @@ public TextView(Context context,
11341130
setLongClickable(longClickable);
11351131

11361132
prepareCursorControllers();
1137-
1138-
final ViewConfiguration viewConfiguration = ViewConfiguration.get(context);
1139-
final int touchSlop = viewConfiguration.getScaledTouchSlop();
1140-
mSquaredTouchSlopDistance = touchSlop * touchSlop;
11411133
}
11421134

11431135
private void setTypefaceByIndex(int typefaceIndex, int styleIndex) {
@@ -3202,8 +3194,7 @@ private void setText(CharSequence text, BufferType type,
32023194

32033195
int n = mFilters.length;
32043196
for (int i = 0; i < n; i++) {
3205-
CharSequence out = mFilters[i].filter(text, 0, text.length(),
3206-
EMPTY_SPANNED, 0, 0);
3197+
CharSequence out = mFilters[i].filter(text, 0, text.length(), EMPTY_SPANNED, 0, 0);
32073198
if (out != null) {
32083199
text = out;
32093200
}
@@ -5621,11 +5612,13 @@ public boolean onKeyUp(int keyCode, KeyEvent event) {
56215612
return super.onKeyUp(keyCode, event);
56225613
}
56235614

5624-
@Override public boolean onCheckIsTextEditor() {
5615+
@Override
5616+
public boolean onCheckIsTextEditor() {
56255617
return mInputType != EditorInfo.TYPE_NULL;
56265618
}
56275619

5628-
@Override public InputConnection onCreateInputConnection(EditorInfo outAttrs) {
5620+
@Override
5621+
public InputConnection onCreateInputConnection(EditorInfo outAttrs) {
56295622
if (onCheckIsTextEditor() && isEnabled()) {
56305623
if (mInputMethodState == null) {
56315624
mInputMethodState = new InputMethodState();
@@ -9248,7 +9241,6 @@ public boolean performLongClick() {
92489241
boolean vibrate = true;
92499242

92509243
if (super.performLongClick()) {
9251-
mDiscardNextActionUp = true;
92529244
handled = true;
92539245
}
92549246

@@ -10798,7 +10790,12 @@ public boolean onTouchEvent(MotionEvent ev) {
1079810790
final float deltaX = mDownPositionX - ev.getRawX();
1079910791
final float deltaY = mDownPositionY - ev.getRawY();
1080010792
final float distanceSquared = deltaX * deltaX + deltaY * deltaY;
10801-
if (distanceSquared < mSquaredTouchSlopDistance) {
10793+
10794+
final ViewConfiguration viewConfiguration = ViewConfiguration.get(
10795+
TextView.this.getContext());
10796+
final int touchSlop = viewConfiguration.getScaledTouchSlop();
10797+
10798+
if (distanceSquared < touchSlop * touchSlop) {
1080210799
if (mActionPopupWindow != null && mActionPopupWindow.isShowing()) {
1080310800
// Tapping on the handle dismisses the displayed action popup
1080410801
mActionPopupWindow.hide();
@@ -11012,7 +11009,8 @@ private class SelectionModifierCursorController implements CursorController {
1101211009

1101311010
// Double tap detection
1101411011
private long mPreviousTapUpTime = 0;
11015-
private float mPreviousTapPositionX, mPreviousTapPositionY;
11012+
private float mDownPositionX, mDownPositionY;
11013+
private boolean mGestureStayedInTapRegion;
1101611014

1101711015
SelectionModifierCursorController() {
1101811016
resetTouchOffsets();
@@ -11075,20 +11073,28 @@ public void onTouchEvent(MotionEvent event) {
1107511073
mMinTouchOffset = mMaxTouchOffset = getOffsetForPosition(x, y);
1107611074

1107711075
// Double tap detection
11078-
long duration = SystemClock.uptimeMillis() - mPreviousTapUpTime;
11079-
if (duration <= ViewConfiguration.getDoubleTapTimeout() &&
11080-
isPositionOnText(x, y)) {
11081-
final float deltaX = x - mPreviousTapPositionX;
11082-
final float deltaY = y - mPreviousTapPositionY;
11083-
final float distanceSquared = deltaX * deltaX + deltaY * deltaY;
11084-
if (distanceSquared < mSquaredTouchSlopDistance) {
11085-
startSelectionActionMode();
11086-
mDiscardNextActionUp = true;
11076+
if (mGestureStayedInTapRegion) {
11077+
long duration = SystemClock.uptimeMillis() - mPreviousTapUpTime;
11078+
if (duration <= ViewConfiguration.getDoubleTapTimeout()) {
11079+
final float deltaX = x - mDownPositionX;
11080+
final float deltaY = y - mDownPositionY;
11081+
final float distanceSquared = deltaX * deltaX + deltaY * deltaY;
11082+
11083+
ViewConfiguration viewConfiguration = ViewConfiguration.get(
11084+
TextView.this.getContext());
11085+
int doubleTapSlop = viewConfiguration.getScaledDoubleTapSlop();
11086+
boolean stayedInArea = distanceSquared < doubleTapSlop * doubleTapSlop;
11087+
11088+
if (stayedInArea && isPositionOnText(x, y)) {
11089+
startSelectionActionMode();
11090+
mDiscardNextActionUp = true;
11091+
}
1108711092
}
1108811093
}
1108911094

11090-
mPreviousTapPositionX = x;
11091-
mPreviousTapPositionY = y;
11095+
mDownPositionX = x;
11096+
mDownPositionY = y;
11097+
mGestureStayedInTapRegion = true;
1109211098
break;
1109311099

1109411100
case MotionEvent.ACTION_POINTER_DOWN:
@@ -11101,6 +11107,22 @@ public void onTouchEvent(MotionEvent event) {
1110111107
}
1110211108
break;
1110311109

11110+
case MotionEvent.ACTION_MOVE:
11111+
if (mGestureStayedInTapRegion) {
11112+
final float deltaX = event.getX() - mDownPositionX;
11113+
final float deltaY = event.getY() - mDownPositionY;
11114+
final float distanceSquared = deltaX * deltaX + deltaY * deltaY;
11115+
11116+
final ViewConfiguration viewConfiguration = ViewConfiguration.get(
11117+
TextView.this.getContext());
11118+
int doubleTapTouchSlop = viewConfiguration.getScaledDoubleTapTouchSlop();
11119+
11120+
if (distanceSquared > doubleTapTouchSlop * doubleTapTouchSlop) {
11121+
mGestureStayedInTapRegion = false;
11122+
}
11123+
}
11124+
break;
11125+
1110411126
case MotionEvent.ACTION_UP:
1110511127
mPreviousTapUpTime = SystemClock.uptimeMillis();
1110611128
break;

0 commit comments

Comments
 (0)