summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAdam Powell <adamp@google.com>2010-10-02 18:12:02 -0700
committerAdam Powell <adamp@google.com>2010-10-02 18:31:38 -0700
commit624380a14def6c2acdb473e09c36139acbcefbf9 (patch)
treefb9c672ffbfe7e18a3561d73228c5c26869eecae
parent03876c905f3874f3ac8deb5a23ee0f77d4c04bab (diff)
downloadframeworks_base-624380a14def6c2acdb473e09c36139acbcefbf9.zip
frameworks_base-624380a14def6c2acdb473e09c36139acbcefbf9.tar.gz
frameworks_base-624380a14def6c2acdb473e09c36139acbcefbf9.tar.bz2
Fix bug 3047653 - Text select handles stick around when they shouldn't
Text select handles will now fade out on their own after a few seconds since many apps expect a selection to be persistent while a text field stays focused in touch mode. The user may tap within the selection to bring the anchors back. Text select handles will also disappear upon leaving touch mode. Fix a bug that impaired cut/paste from the context menu. Change-Id: I8f431e2d261aec02581150125d11324a3ee11656
-rw-r--r--core/java/android/widget/TextView.java76
1 files changed, 68 insertions, 8 deletions
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 72df726..fbcc9dc 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) {
@@ -6621,7 +6637,10 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
if (mInputContentType != null) {
mInputContentType.enterDown = false;
}
- hideControllers();
+ hideInsertionPointCursorController();
+ if (mSelectionModifierCursorController != null) {
+ mSelectionModifierCursorController.hide();
+ }
}
startStopMarquee(hasWindowFocus);
@@ -6631,7 +6650,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();
+ }
}
}
@@ -6669,8 +6691,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
@@ -6680,6 +6710,8 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
mInsertionPointCursorController.show();
}
}
+ } else if (hasSelection() && mSelectionModifierCursorController != null) {
+ mSelectionModifierCursorController.show();
}
}
@@ -7627,7 +7659,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()}.
@@ -7882,6 +7914,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 {
@@ -7892,6 +7930,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));
@@ -7904,12 +7950,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() {
@@ -7975,6 +8028,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) {
@@ -8031,6 +8085,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() {