diff options
| -rw-r--r-- | core/java/android/widget/TextView.java | 96 |
1 files changed, 79 insertions, 17 deletions
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java index 623cd4180c3d..1604fde64e6d 100644 --- a/core/java/android/widget/TextView.java +++ b/core/java/android/widget/TextView.java @@ -7931,9 +7931,6 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener max = Math.max(0, Math.max(selStart, selEnd)); } - ClipboardManager clipboard = (ClipboardManager)getContext() - .getSystemService(Context.CLIPBOARD_SERVICE); - switch (id) { case ID_COPY_URL: URLSpan[] urls = ((Spanned) mText).getSpans(min, max, URLSpan.class); @@ -8404,8 +8401,12 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener */ public void updatePosition(HandleView handle, int x, int y); + public void updateOffset(HandleView handle, int offset); + public void updatePosition(); + public int getCurrentOffset(HandleView handle); + /** * This method is called by {@link #onTouchEvent(MotionEvent)} and gives the controller * a chance to become active and/or visible. @@ -8422,7 +8423,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener } private class PastePopupMenu implements OnClickListener { - private PopupWindow mContainer; + private final PopupWindow mContainer; private int mPositionX; private int mPositionY; private View mPasteView, mNoPasteView; @@ -8521,12 +8522,11 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener } private class HandleView extends View { - private boolean mPositionOnTop = false; private Drawable mDrawable; - private PopupWindow mContainer; + private final PopupWindow mContainer; private int mPositionX; private int mPositionY; - private CursorController mController; + private final CursorController mController; private boolean mIsDragging; private float mTouchToWindowOffsetX; private float mTouchToWindowOffsetY; @@ -8543,6 +8543,46 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener private PastePopupMenu mPastePopupWindow; private Runnable mLongPressCallback; + // Touch-up filter: number of previous positions remembered + private static final int HISTORY_SIZE = 5; + private static final int TOUCH_UP_FILTER_DELAY = 150; + private final long[] mPreviousOffsetsTimes = new long[HISTORY_SIZE]; + private final int[] mPreviousOffsets = new int[HISTORY_SIZE]; + private int mPreviousOffsetIndex = 0; + private int mNumberPreviousOffsets = 0; + + public void startTouchUpFilter(int offset) { + mNumberPreviousOffsets = 0; + addPositionToTouchUpFilter(offset); + } + + public void addPositionToTouchUpFilter(int offset) { + if (mNumberPreviousOffsets > 0 && + mPreviousOffsets[mPreviousOffsetIndex] == offset) { + // Make sure only actual changes of position are recorded. + return; + } + + mPreviousOffsetIndex = (mPreviousOffsetIndex + 1) % HISTORY_SIZE; + mPreviousOffsets[mPreviousOffsetIndex] = offset; + mPreviousOffsetsTimes[mPreviousOffsetIndex] = SystemClock.uptimeMillis(); + mNumberPreviousOffsets++; + } + + public void filterOnTouchUp() { + final long now = SystemClock.uptimeMillis(); + int i = 0; + int index = 0; + final int iMax = Math.min(mNumberPreviousOffsets, HISTORY_SIZE); + while (i < iMax) { + index = (mPreviousOffsetIndex - i + HISTORY_SIZE) % HISTORY_SIZE; + if ((now - mPreviousOffsetsTimes[index]) >= TOUCH_UP_FILTER_DELAY) break; + i++; + } + + mController.updateOffset(this, mPreviousOffsets[index]); + } + public static final int LEFT = 0; public static final int CENTER = 1; public static final int RIGHT = 2; @@ -8738,20 +8778,14 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener @Override protected void onDraw(Canvas c) { mDrawable.setBounds(0, 0, mRight - mLeft, mBottom - mTop); - if (mPositionOnTop) { - c.save(); - c.rotate(180, (mRight - mLeft) / 2, (mBottom - mTop) / 2); - mDrawable.draw(c); - c.restore(); - } else { - mDrawable.draw(c); - } + mDrawable.draw(c); } @Override public boolean onTouchEvent(MotionEvent ev) { switch (ev.getActionMasked()) { case MotionEvent.ACTION_DOWN: { + startTouchUpFilter(mController.getCurrentOffset(this)); mDownPositionX = ev.getRawX(); mDownPositionY = ev.getRawY(); mTouchToWindowOffsetX = mDownPositionX - mPositionX; @@ -8808,6 +8842,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener } } } + filterOnTouchUp(); mIsDragging = false; break; @@ -8825,6 +8860,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener } void positionAtCursor(final int offset, boolean bottom) { + addPositionToTouchUpFilter(offset); final int width = mDrawable.getIntrinsicWidth(); final int height = mDrawable.getIntrinsicHeight(); final int line = mLayout.getLineForOffset(offset); @@ -8940,12 +8976,16 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener int offset = getHysteresisOffset(x, y, previousOffset); if (offset != previousOffset) { - Selection.setSelection((Spannable) mText, offset); - updatePosition(); + updateOffset(handle, offset); } hideDelayed(); } + public void updateOffset(HandleView handle, int offset) { + Selection.setSelection((Spannable) mText, offset); + updatePosition(); + } + public void updatePosition() { final int offset = getSelectionStart(); @@ -8959,6 +8999,10 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener getHandle().positionAtCursor(offset, true); } + public int getCurrentOffset(HandleView handle) { + return getSelectionStart(); + } + public boolean onTouchEvent(MotionEvent ev) { return false; } @@ -9069,6 +9113,20 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener updatePosition(); } + public void updateOffset(HandleView handle, int offset) { + int start = getSelectionStart(); + int end = getSelectionEnd(); + + if (mStartHandle == handle) { + start = offset; + } else { + end = offset; + } + + Selection.setSelection((Spannable) mText, start, end); + updatePosition(); + } + public void updatePosition() { if (!isShowing()) { return; @@ -9089,6 +9147,10 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener mEndHandle.positionAtCursor(selectionEnd, true); } + public int getCurrentOffset(HandleView handle) { + return mStartHandle == handle ? getSelectionStart() : getSelectionEnd(); + } + public boolean onTouchEvent(MotionEvent event) { // This is done even when the View does not have focus, so that long presses can start // selection and tap can move cursor from this tap position. |