diff options
| -rw-r--r-- | core/java/android/widget/Editor.java | 3 | ||||
| -rw-r--r-- | core/java/android/widget/SelectionActionModeHelper.java | 45 | ||||
| -rw-r--r-- | core/java/android/widget/TextView.java | 2 |
3 files changed, 32 insertions, 18 deletions
diff --git a/core/java/android/widget/Editor.java b/core/java/android/widget/Editor.java index 31d878f7a50b..f1f25bf82b7f 100644 --- a/core/java/android/widget/Editor.java +++ b/core/java/android/widget/Editor.java @@ -1250,7 +1250,8 @@ public class Editor { } } - void sendOnTextChanged(int start, int after) { + void sendOnTextChanged(int start, int before, int after) { + getSelectionActionModeHelper().onTextChanged(start, start + before); updateSpellCheckSpans(start, start + after, false); // Flip flag to indicate the word iterator needs to have the text reset. diff --git a/core/java/android/widget/SelectionActionModeHelper.java b/core/java/android/widget/SelectionActionModeHelper.java index aafa343fc96c..4ebb3cfea266 100644 --- a/core/java/android/widget/SelectionActionModeHelper.java +++ b/core/java/android/widget/SelectionActionModeHelper.java @@ -122,10 +122,8 @@ final class SelectionActionModeHelper { SelectionEvent.ActionType.DRAG, mTextClassification); } - public void onTypeOverSelection() { - mSelectionTracker.onSelectionAction( - mTextView.getSelectionStart(), mTextView.getSelectionEnd(), - SelectionEvent.ActionType.OVERTYPE, mTextClassification); + public void onTextChanged(int start, int end) { + mSelectionTracker.onTextChanged(start, end, mTextClassification); } public boolean resetSelection(int textIndex) { @@ -217,7 +215,6 @@ final class SelectionActionModeHelper { private int mOriginalEnd; private int mSelectionStart; private int mSelectionEnd; - private boolean mSelectionStarted; private boolean mAllowReset; SelectionTracker(TextView textView) { @@ -230,9 +227,8 @@ final class SelectionActionModeHelper { */ public void onOriginalSelection( CharSequence text, int selectionStart, int selectionEnd, boolean editableText) { - mOriginalStart = selectionStart; - mOriginalEnd = selectionEnd; - mSelectionStarted = true; + mOriginalStart = mSelectionStart = selectionStart; + mOriginalEnd = mSelectionEnd = selectionEnd; mAllowReset = false; maybeInvalidateLogger(); mLogger.logSelectionStarted(text, selectionStart); @@ -242,7 +238,7 @@ final class SelectionActionModeHelper { * Called when selection action mode is started and the results come from a classifier. */ public void onSmartSelection(SelectionResult result) { - if (mSelectionStarted) { + if (isSelectionStarted()) { mSelectionStart = result.mStart; mSelectionEnd = result.mEnd; mAllowReset = mSelectionStart != mOriginalStart || mSelectionEnd != mOriginalEnd; @@ -257,7 +253,9 @@ final class SelectionActionModeHelper { public void onSelectionUpdated( int selectionStart, int selectionEnd, @Nullable TextClassification classification) { - if (mSelectionStarted) { + if (isSelectionStarted()) { + mSelectionStart = selectionStart; + mSelectionEnd = selectionEnd; mAllowReset = false; mLogger.logSelectionModified(selectionStart, selectionEnd, classification, null); } @@ -268,10 +266,13 @@ final class SelectionActionModeHelper { */ public void onSelectionDestroyed() { mAllowReset = false; - mSelectionStarted = false; - mLogger.logSelectionAction( - mSelectionStart, mSelectionEnd, - SelectionEvent.ActionType.ABANDON, null /* classification */); + // Wait a few ms to see if the selection was destroyed because of a text change event. + mTextView.postDelayed(() -> { + mLogger.logSelectionAction( + mSelectionStart, mSelectionEnd, + SelectionEvent.ActionType.ABANDON, null /* classification */); + mSelectionStart = mSelectionEnd = -1; + }, 100 /* ms */); } /** @@ -281,7 +282,7 @@ final class SelectionActionModeHelper { int selectionStart, int selectionEnd, @SelectionEvent.ActionType int action, @Nullable TextClassification classification) { - if (mSelectionStarted) { + if (isSelectionStarted()) { mAllowReset = false; mLogger.logSelectionAction(selectionStart, selectionEnd, action, classification); } @@ -295,13 +296,15 @@ final class SelectionActionModeHelper { */ public boolean resetSelection(int textIndex, Editor editor) { final TextView textView = editor.getTextView(); - if (mSelectionStarted + if (isSelectionStarted() && mAllowReset && textIndex >= mSelectionStart && textIndex <= mSelectionEnd && textView.getText() instanceof Spannable) { mAllowReset = false; boolean selected = editor.selectCurrentWord(); if (selected) { + mSelectionStart = editor.getTextView().getSelectionStart(); + mSelectionEnd = editor.getTextView().getSelectionEnd(); mLogger.logSelectionAction( textView.getSelectionStart(), textView.getSelectionEnd(), SelectionEvent.ActionType.RESET, null /* classification */); @@ -311,11 +314,21 @@ final class SelectionActionModeHelper { return false; } + public void onTextChanged(int start, int end, TextClassification classification) { + if (isSelectionStarted() && start == mSelectionStart && end == mSelectionEnd) { + onSelectionAction(start, end, SelectionEvent.ActionType.OVERTYPE, classification); + } + } + private void maybeInvalidateLogger() { if (mLogger.isEditTextLogger() != mTextView.isTextEditable()) { mLogger = new SelectionMetricsLogger(mTextView); } } + + private boolean isSelectionStarted() { + return mSelectionStart >= 0 && mSelectionEnd >= 0 && mSelectionStart != mSelectionEnd; + } } // TODO: Write tests diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java index cd2d2fdf5a8a..11fe67c0564c 100644 --- a/core/java/android/widget/TextView.java +++ b/core/java/android/widget/TextView.java @@ -9364,7 +9364,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener } } - if (mEditor != null) mEditor.sendOnTextChanged(start, after); + if (mEditor != null) mEditor.sendOnTextChanged(start, before, after); } /** |