diff options
author | Gilles Debunne <debunne@google.com> | 2011-01-11 14:35:39 -0800 |
---|---|---|
committer | android-merger <android-build@android.com> | 2011-02-08 14:10:30 -0800 |
commit | 3145ab8c1be61a63890b367f2a0e7d0056f2694f (patch) | |
tree | bf807fb1ac6c2d9631fdc68da5cbdd54c10c4bde | |
parent | 81244066b0aec5f0a87702f190a620ecdf896e83 (diff) | |
download | base-3145ab8c1be61a63890b367f2a0e7d0056f2694f.tar.gz |
SelectAllOnFocus shows a higlighted text. DO NOT MERGE.
Bug 3201383
Highlighted is different from selected, only the background is modified
and selection mode is not started.
Tapping inside a highlighted text places the cursor. This is especially
useful for WebView and search bar has been modified to select all on focus.
Selection handles time out is no longer needed.
This CL is pretty involved and especially messes up with the terrible
ExtractedTextView, which causes a lot of problem with text selection
across device rotations.
The current implementation works pretty well. It has one problem: the handles
are not displayed when switching to landscape mode with a selected text.
This is still an improvement over the current GB version, where the handles
are not preserved at all across device rotation and where I can find more bugs.
Handles are now hidden when a context menu is displayed.
I can polish this more if we decide to include this in the MR1.
Change-Id: Id10bf2808ff25752efd59a1987e91d609ba478cd
-rw-r--r-- | core/java/android/widget/TextView.java | 94 | ||||
-rw-r--r-- | core/res/res/layout/search_bar.xml | 1 |
2 files changed, 37 insertions, 58 deletions
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java index fba27af8bc90..ed1769692b20 100644 --- a/core/java/android/widget/TextView.java +++ b/core/java/android/widget/TextView.java @@ -297,6 +297,9 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener Drawable mSelectHandleRight; Drawable mSelectHandleCenter; + // Set when this TextView gained focus with some text selected. Will start selection mode. + private boolean mCreatedWithASelection = false; + /* * Kick-start the font cache for the zygote process (to pay the cost of * initializing freetype for our default font only once). @@ -3758,8 +3761,10 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener // - ExtractEditText does not call onFocus when it is displayed. Fixing this issue would // allow to test for hasSelection in onFocusChanged, which would trigger a // startTextSelectionMode here. TODO - if (this instanceof ExtractEditText && selectionController != null && hasSelection()) { + if (mCreatedWithASelection || + (this instanceof ExtractEditText && selectionController != null && hasSelection())) { startTextSelectionMode(); + mCreatedWithASelection = false; } mPreDrawState = PREDRAW_DONE; @@ -4175,6 +4180,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener mInsertionPointCursorController.isShowing()) { mInsertionPointCursorController.updatePosition(); } + if (mSelectionModifierCursorController != null && mSelectionModifierCursorController.isShowing()) { mSelectionModifierCursorController.updatePosition(); @@ -6580,6 +6586,12 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener int selStart = getSelectionStart(); int selEnd = getSelectionEnd(); + // SelectAllOnFocus fields are highlighted and not selected. Do not start text selection + // mode for these, unless there was a specific selection already started. + final boolean isFocusHighlighted = mSelectAllOnFocus && selStart == 0 && + selEnd == mText.length(); + mCreatedWithASelection = mFrozenWithFocus && hasSelection() && !isFocusHighlighted; + if (!mFrozenWithFocus || (selStart < 0 || selEnd < 0)) { // If a tap was used to give focus to that view, move cursor at tap position. // Has to be done before onTakeFocus, which can be overloaded. @@ -6592,10 +6604,6 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener mMovement.onTakeFocus(this, (Spannable) mText, direction); } - if (mSelectAllOnFocus) { - Selection.setSelection((Spannable) mText, 0, mText.length()); - } - // The DecorView does not have focus when the 'Done' ExtractEditText button is // pressed. Since it is the ViewRoot's mView, it requests focus before // ExtractEditText clears focus, which gives focus to the ExtractEditText. @@ -6614,6 +6622,11 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener */ Selection.setSelection((Spannable) mText, selStart, selEnd); } + + if (mSelectAllOnFocus) { + Selection.setSelection((Spannable) mText, 0, mText.length()); + } + mTouchFocusSelected = true; } @@ -6643,7 +6656,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener // ExtractEditText goes out of focus. mIsInTextSelectionMode = false; } else { - terminateTextSelectionMode(); + stopTextSelectionMode(); } if (mSelectionModifierCursorController != null) { @@ -6745,29 +6758,23 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener final int end = getSelectionEnd(); if (start == end) { - if (start >= prevStart && start < prevEnd) { + boolean tapInsideSelectAllOnFocus = mSelectAllOnFocus && prevStart == 0 && + prevEnd == mText.length(); + if (start >= prevStart && start < prevEnd && !tapInsideSelectAllOnFocus) { // Restore previous selection Selection.setSelection((Spannable)mText, prevStart, prevEnd); - if (hasSelectionController() && !getSelectionController().isShowing()) { - // If the anchors aren't showing, revive them. - getSelectionController().show(); - } else { - // Tapping inside the selection displays the cut/copy/paste context menu - // as long as the anchors are already showing. - showContextMenu(); - } - return; + // Tapping inside the selection displays the cut/copy/paste context menu + showContextMenu(); } else { // Tapping outside stops selection mode, if any stopTextSelectionMode(); - if (hasInsertionController() && mText.length() > 0) { + boolean selectAllGotFocus = mSelectAllOnFocus && mTouchFocusSelected; + if (hasInsertionController() && !selectAllGotFocus) { getInsertionController().show(); } } - } else if (hasSelection() && hasSelectionController()) { - getSelectionController().show(); } } @@ -6790,7 +6797,8 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener int end = Math.min(len, mPrevEnd); Selection.setSelection((Spannable)mText, start, end); - if (hasSelection()) { + boolean selectAllGotFocus = mSelectAllOnFocus && mTouchFocusSelected; + if (hasSelection() && !selectAllGotFocus) { startTextSelectionMode(); } } @@ -7147,7 +7155,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener } private boolean canSelectText() { - return textCanBeSelected() && mText.length() != 0; + return hasSelectionController() && mText.length() != 0; } private boolean textCanBeSelected() { @@ -7317,7 +7325,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener } int selectionStart, selectionEnd; - + long wordLimits = getWordLimitsAt(minOffset); if (wordLimits >= 0) { selectionStart = extractRangeStartFromLong(wordLimits); @@ -7476,6 +7484,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener } if (added) { + hideControllers(); menu.setHeaderTitle(com.android.internal.R.string.editTextMenuTitle); } } @@ -7652,29 +7661,18 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener return; } - if (!requestFocus()) { + if (!canSelectText() || !requestFocus()) { return; } selectCurrentWord(); + getSelectionController().show(); + final InputMethodManager imm = (InputMethodManager) + getContext().getSystemService(Context.INPUT_METHOD_SERVICE); + imm.showSoftInput(this, 0, null); mIsInTextSelectionMode = true; } } - - /** - * Same as {@link #stopTextSelectionMode()}, except that there is no cursor controller - * fade out animation. Needed since the drawable and their alpha values are shared by all - * TextViews. Switching from one TextView to another would fade the cursor controllers in the - * new one otherwise. - */ - private void terminateTextSelectionMode() { - stopTextSelectionMode(); - if (mSelectionModifierCursorController != null) { - SelectionModifierCursorController selectionModifierCursorController = - (SelectionModifierCursorController) mSelectionModifierCursorController; - selectionModifierCursorController.cancelFadeOutAnimation(); - } - } private void stopTextSelectionMode() { if (mIsInTextSelectionMode) { @@ -8052,14 +8050,6 @@ 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() { mStartHandle = new HandleView(this, HandleView.LEFT); mEndHandle = new HandleView(this, HandleView.RIGHT); @@ -8076,29 +8066,18 @@ 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() { return mIsShowing; } - public void cancelFadeOutAnimation() { - hide(); - } - public void updatePosition(HandleView handle, int x, int y) { int selectionStart = getSelectionStart(); int selectionEnd = getSelectionEnd(); @@ -8150,7 +8129,6 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener mStartHandle.positionAtCursor(selectionStart, true); mEndHandle.positionAtCursor(selectionEnd, true); - hideDelayed(DELAY_BEFORE_FADE_OUT); } public boolean onTouchEvent(MotionEvent event) { diff --git a/core/res/res/layout/search_bar.xml b/core/res/res/layout/search_bar.xml index 7935e2a3fd53..c7c073c4438c 100644 --- a/core/res/res/layout/search_bar.xml +++ b/core/res/res/layout/search_bar.xml @@ -75,6 +75,7 @@ android:drawablePadding="2dip" android:singleLine="true" android:ellipsize="end" + android:selectAllOnFocus="true" android:inputType="text|textAutoComplete" android:dropDownWidth="match_parent" android:dropDownHeight="match_parent" |