diff options
| -rw-r--r-- | core/java/android/widget/TextView.java | 76 |
1 files changed, 68 insertions, 8 deletions
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java index c6f2754cb2dc..6dbb4c8ff5d5 100644 --- a/core/java/android/widget/TextView.java +++ b/core/java/android/widget/TextView.java @@ -3751,18 +3751,34 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener showError(); mShowErrorAfterAttach = false; } + + final ViewTreeObserver observer = getViewTreeObserver(); + if (observer != null) { + if (mInsertionPointCursorController != null) { + observer.addOnTouchModeChangeListener(mInsertionPointCursorController); + } + if (mSelectionModifierCursorController != null) { + observer.addOnTouchModeChangeListener(mSelectionModifierCursorController); + } + } } @Override protected void onDetachedFromWindow() { super.onDetachedFromWindow(); - if (mPreDrawState != PREDRAW_NOT_REGISTERED) { - final ViewTreeObserver observer = getViewTreeObserver(); - if (observer != null) { + final ViewTreeObserver observer = getViewTreeObserver(); + if (observer != null) { + if (mPreDrawState != PREDRAW_NOT_REGISTERED) { observer.removeOnPreDrawListener(this); mPreDrawState = PREDRAW_NOT_REGISTERED; } + if (mInsertionPointCursorController != null) { + observer.removeOnTouchModeChangeListener(mInsertionPointCursorController); + } + if (mSelectionModifierCursorController != null) { + observer.removeOnTouchModeChangeListener(mSelectionModifierCursorController); + } } if (mError != null) { @@ -6626,7 +6642,10 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener if (mInputContentType != null) { mInputContentType.enterDown = false; } - hideControllers(); + hideInsertionPointCursorController(); + if (mSelectionModifierCursorController != null) { + mSelectionModifierCursorController.hide(); + } } startStopMarquee(hasWindowFocus); @@ -6636,7 +6655,10 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener protected void onVisibilityChanged(View changedView, int visibility) { super.onVisibilityChanged(changedView, visibility); if (visibility != VISIBLE) { - hideControllers(); + hideInsertionPointCursorController(); + if (mSelectionModifierCursorController != null) { + mSelectionModifierCursorController.hide(); + } } } @@ -6674,8 +6696,16 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener if (start >= prevStart && start < prevEnd) { // Restore previous selection Selection.setSelection((Spannable)mText, prevStart, prevEnd); - // Tapping inside the selection displays the cut/copy/paste context menu. - showContextMenu(); + + if (mSelectionModifierCursorController != null && + !mSelectionModifierCursorController.isShowing()) { + // If the anchors aren't showing, revive them. + mSelectionModifierCursorController.show(); + } else { + // Tapping inside the selection displays the cut/copy/paste context menu + // as long as the anchors are already showing. + showContextMenu(); + } return; } else { // Tapping outside stops selection mode, if any @@ -6685,6 +6715,8 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener mInsertionPointCursorController.show(); } } + } else if (hasSelection() && mSelectionModifierCursorController != null) { + mSelectionModifierCursorController.show(); } } @@ -7632,7 +7664,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener * It is not used outside of {@link TextView}. * @hide */ - private interface CursorController { + private interface CursorController extends ViewTreeObserver.OnTouchModeChangeListener { /** * Makes the cursor controller visible on screen. Will be drawn by {@link #draw(Canvas)}. * See also {@link #hide()}. @@ -7887,6 +7919,12 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener public boolean onTouchEvent(MotionEvent ev) { return false; } + + public void onTouchModeChanged(boolean isInTouchMode) { + if (!isInTouchMode) { + hide(); + } + } } private class SelectionModifierCursorController implements CursorController { @@ -7897,6 +7935,14 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener // Whether selection anchors are active private boolean mIsShowing; + private static final int DELAY_BEFORE_FADE_OUT = 4100; + + private final Runnable mHider = new Runnable() { + public void run() { + hide(); + } + }; + SelectionModifierCursorController() { Resources res = mContext.getResources(); mStartHandle = new HandleView(this, res.getDrawable(mTextSelectHandleLeftRes)); @@ -7909,12 +7955,19 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener mStartHandle.show(); mEndHandle.show(); hideInsertionPointCursorController(); + hideDelayed(DELAY_BEFORE_FADE_OUT); } public void hide() { mStartHandle.hide(); mEndHandle.hide(); mIsShowing = false; + removeCallbacks(mHider); + } + + private void hideDelayed(int delay) { + removeCallbacks(mHider); + postDelayed(mHider, delay); } public boolean isShowing() { @@ -7980,6 +8033,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener mLayout.getLineForOffset(selectionEnd); mStartHandle.positionAtCursor(selectionStart, oneLineSelection); mEndHandle.positionAtCursor(selectionEnd, true); + hideDelayed(DELAY_BEFORE_FADE_OUT); } public boolean onTouchEvent(MotionEvent event) { @@ -8036,6 +8090,12 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener public boolean isSelectionStartDragged() { return mStartHandle.isDragging(); } + + public void onTouchModeChanged(boolean isInTouchMode) { + if (!isInTouchMode) { + hide(); + } + } } private void hideInsertionPointCursorController() { |