diff options
| -rw-r--r-- | core/java/android/widget/TextView.java | 126 |
1 files changed, 95 insertions, 31 deletions
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java index 5320b101ca45..b143325ae071 100644 --- a/core/java/android/widget/TextView.java +++ b/core/java/android/widget/TextView.java @@ -3869,7 +3869,7 @@ 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 (selectionController != null && hasSelection()) { + if (this instanceof ExtractEditText && selectionController != null && hasSelection()) { startSelectionActionMode(); } @@ -5042,6 +5042,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener } public void beginBatchEdit() { + mInBatchEditControllers = true; final InputMethodState ims = mInputMethodState; if (ims != null) { int nesting = ++ims.mBatchEditNesting; @@ -5064,6 +5065,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener } public void endBatchEdit() { + mInBatchEditControllers = false; final InputMethodState ims = mInputMethodState; if (ims != null) { int nesting = --ims.mBatchEditNesting; @@ -6991,26 +6993,21 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener // Restore previous selection Selection.setSelection((Spannable)mText, prevStart, prevEnd); - if (mSelectionModifierCursorController != null && - !mSelectionModifierCursorController.isShowing()) { + if (hasSelectionController() && !getSelectionController().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(); + getSelectionController().show(); } return; } else { // Tapping outside stops selection mode, if any stopSelectionActionMode(); - if (mInsertionPointCursorController != null) { - mInsertionPointCursorController.show(); + if (hasInsertionController()) { + getInsertionController().show(); } } - } else if (hasSelection() && mSelectionModifierCursorController != null) { - mSelectionModifierCursorController.show(); + } else if (hasSelection() && hasSelectionController()) { + getSelectionController().show(); } } @@ -7043,11 +7040,12 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener @Override public boolean onTouchEvent(MotionEvent event) { final int action = event.getActionMasked(); - if (mInsertionPointCursorController != null) { - mInsertionPointCursorController.onTouchEvent(event); + + if (hasInsertionController()) { + getInsertionController().onTouchEvent(event); } - if (mSelectionModifierCursorController != null) { - mSelectionModifierCursorController.onTouchEvent(event); + if (hasSelectionController()) { + getSelectionController().onTouchEvent(event); } if (action == MotionEvent.ACTION_DOWN) { @@ -7129,21 +7127,17 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener || windowParams.type > WindowManager.LayoutParams.LAST_SUB_WINDOW; } - if (windowSupportsHandles && isTextEditable() && mCursorVisible && mLayout != null && - !mTextIsSelectable) { - if (mInsertionPointCursorController == null) { - mInsertionPointCursorController = new InsertionPointCursorController(); - } - } else { - hideInsertionPointCursorController(); + // TODO Add an extra android:cursorController flag to disable the controller? + mInsertionControllerEnabled = windowSupportsHandles && isTextEditable() && mCursorVisible && + mLayout != null && !mTextIsSelectable; + mSelectionControllerEnabled = windowSupportsHandles && textCanBeSelected() && + mLayout != null; + + if (!mInsertionControllerEnabled) { mInsertionPointCursorController = null; } - if (windowSupportsHandles && textCanBeSelected() && mLayout != null) { - if (mSelectionModifierCursorController == null) { - mSelectionModifierCursorController = new SelectionModifierCursorController(); - } - } else { + if (!mSelectionControllerEnabled) { // Stop selection mode if the controller becomes unavailable. if (mSelectionModifierCursorController != null) { stopSelectionActionMode(); @@ -8348,6 +8342,10 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener return true; } + if (isInBatchEditMode()) { + return false; + } + final int extendedPaddingTop = getExtendedPaddingTop(); final int extendedPaddingBottom = getExtendedPaddingBottom(); final int compoundPaddingLeft = getCompoundPaddingLeft(); @@ -8387,7 +8385,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener mPositionY = y - TextView.this.mScrollY; if (isPositionVisible()) { int[] coords = null; - if (mContainer.isShowing()){ + if (mContainer.isShowing()) { coords = mTempCoords; TextView.this.getLocationInWindow(coords); final int containerPositionX = coords[0] + mPositionX; @@ -8626,6 +8624,10 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener } public void show() { + if (isInBatchEditMode()) { + return; + } + mIsShowing = true; updatePosition(); mStartHandle.show(); @@ -8689,6 +8691,10 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener } public void updatePosition() { + if (!isShowing()) { + return; + } + final int selectionStart = getSelectionStart(); final int selectionEnd = getSelectionEnd(); @@ -8913,8 +8919,62 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener } } + /** + * @return True if this view supports insertion handles. + */ + boolean hasInsertionController() { + return mInsertionControllerEnabled; + } + + /** + * @return True if this view supports selection handles. + */ + boolean hasSelectionController() { + return mSelectionControllerEnabled; + } + + CursorController getInsertionController() { + if (!mInsertionControllerEnabled) { + return null; + } + + if (mInsertionPointCursorController == null) { + mInsertionPointCursorController = new InsertionPointCursorController(); + + final ViewTreeObserver observer = getViewTreeObserver(); + if (observer != null) { + observer.addOnTouchModeChangeListener(mInsertionPointCursorController); + } + } + + return mInsertionPointCursorController; + } + + CursorController getSelectionController() { + if (!mSelectionControllerEnabled) { + return null; + } + + if (mSelectionModifierCursorController == null) { + mSelectionModifierCursorController = new SelectionModifierCursorController(); + + final ViewTreeObserver observer = getViewTreeObserver(); + if (observer != null) { + observer.addOnTouchModeChangeListener(mSelectionModifierCursorController); + } + } + + return mSelectionModifierCursorController; + } + + boolean isInBatchEditMode() { + final InputMethodState ims = mInputMethodState; + if (ims != null) { + return ims.mBatchEditNesting > 0; + } + return mInBatchEditControllers; + } - @ViewDebug.ExportedProperty(category = "text") private CharSequence mText; private CharSequence mTransformed; private BufferType mBufferType = BufferType.NORMAL; @@ -8942,10 +9002,14 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener private Blink mBlink; private boolean mCursorVisible = true; - // Cursor Controllers. Null when disabled. + // Cursor Controllers. private CursorController mInsertionPointCursorController; private CursorController mSelectionModifierCursorController; private ActionMode mSelectionActionMode; + private boolean mInsertionControllerEnabled; + private boolean mSelectionControllerEnabled; + private boolean mInBatchEditControllers; + // These are needed to desambiguate a long click. If the long click comes from ones of these, we // select from the current cursor position. Otherwise, select from long pressed position. private boolean mDPadCenterIsDown = false; |