diff options
Diffstat (limited to 'core/java/android')
| -rw-r--r-- | core/java/android/view/View.java | 2 | ||||
| -rw-r--r-- | core/java/android/widget/AbsListView.java | 1 | ||||
| -rw-r--r-- | core/java/android/widget/Editor.java | 48 | ||||
| -rw-r--r-- | core/java/android/widget/TextView.java | 8 |
4 files changed, 48 insertions, 11 deletions
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java index bf7d037969cb..c20351b563ad 100644 --- a/core/java/android/view/View.java +++ b/core/java/android/view/View.java @@ -5570,7 +5570,7 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal "unmatched pair of setHasTransientState calls"); } if ((hasTransientState && mTransientStateCount == 1) || - (hasTransientState && mTransientStateCount == 0)) { + (!hasTransientState && mTransientStateCount == 0)) { // update flag if we've just incremented up from 0 or decremented down to 0 mPrivateFlags2 = (mPrivateFlags2 & ~HAS_TRANSIENT_STATE) | (hasTransientState ? HAS_TRANSIENT_STATE : 0); diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java index c4e1bf5391d7..3b4ec7dfaf07 100644 --- a/core/java/android/widget/AbsListView.java +++ b/core/java/android/widget/AbsListView.java @@ -6317,6 +6317,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te if (mTransientStateViews == null) { mTransientStateViews = new SparseArray<View>(); } + scrap.dispatchStartTemporaryDetach(); mTransientStateViews.put(position, scrap); } return; diff --git a/core/java/android/widget/Editor.java b/core/java/android/widget/Editor.java index 4b7ec9ab2c3e..16490e8a0c01 100644 --- a/core/java/android/widget/Editor.java +++ b/core/java/android/widget/Editor.java @@ -16,6 +16,9 @@ package android.widget; +import com.android.internal.util.ArrayUtils; +import com.android.internal.widget.EditableInputConnection; + import android.R; import android.content.ClipData; import android.content.ClipData.Item; @@ -70,10 +73,10 @@ import android.view.Menu; import android.view.MenuItem; import android.view.MotionEvent; import android.view.View; -import android.view.ViewConfiguration; -import android.view.ViewGroup; import android.view.View.DragShadowBuilder; import android.view.View.OnClickListener; +import android.view.ViewConfiguration; +import android.view.ViewGroup; import android.view.ViewGroup.LayoutParams; import android.view.ViewParent; import android.view.ViewTreeObserver; @@ -85,12 +88,12 @@ import android.view.inputmethod.ExtractedTextRequest; import android.view.inputmethod.InputConnection; import android.view.inputmethod.InputMethodManager; import android.widget.AdapterView.OnItemClickListener; +import android.widget.Editor.InputContentType; +import android.widget.Editor.InputMethodState; +import android.widget.Editor.SelectionModifierCursorController; import android.widget.TextView.Drawables; import android.widget.TextView.OnEditorActionListener; -import com.android.internal.util.ArrayUtils; -import com.android.internal.widget.EditableInputConnection; - import java.text.BreakIterator; import java.util.Arrays; import java.util.Comparator; @@ -102,6 +105,8 @@ import java.util.HashMap; * @hide */ public class Editor { + private static final String TAG = "Editor"; + static final int BLINK = 500; private static final float[] TEMP_POSITION = new float[2]; private static int DRAG_SHADOW_MAX_TEXT_LENGTH = 20; @@ -151,6 +156,8 @@ public class Editor { boolean mInBatchEditControllers; boolean mShowSoftInputOnFocus = true; + boolean mPreserveDetachedSelection; + boolean mTemporaryDetach; SuggestionsPopupWindow mSuggestionsPopupWindow; SuggestionRangeSpan mSuggestionRangeSpan; @@ -190,6 +197,7 @@ public class Editor { showError(); mShowErrorAfterAttach = false; } + mTemporaryDetach = false; final ViewTreeObserver observer = mTextView.getViewTreeObserver(); // No need to create the controller. @@ -198,10 +206,22 @@ public class Editor { observer.addOnTouchModeChangeListener(mInsertionPointCursorController); } if (mSelectionModifierCursorController != null) { + mSelectionModifierCursorController.resetTouchOffsets(); observer.addOnTouchModeChangeListener(mSelectionModifierCursorController); } updateSpellCheckSpans(0, mTextView.getText().length(), true /* create the spell checker if needed */); + + if (mTextView.hasTransientState() && + mTextView.getSelectionStart() != mTextView.getSelectionEnd()) { + // Since transient state is reference counted make sure it stays matched + // with our own calls to it for managing selection. + // The action mode callback will set this back again when/if the action mode starts. + mTextView.setHasTransientState(false); + + // We had an active selection from before, start the selection mode. + startSelectionActionMode(); + } } void onDetachedFromWindow() { @@ -234,7 +254,10 @@ public class Editor { mSpellChecker = null; } + mPreserveDetachedSelection = true; hideControllers(); + mPreserveDetachedSelection = false; + mTemporaryDetach = false; } private void showError() { @@ -877,7 +900,9 @@ public class Editor { hideControllers(); Selection.setSelection((Spannable) mTextView.getText(), selStart, selEnd); } else { + if (mTemporaryDetach) mPreserveDetachedSelection = true; hideControllers(); + if (mTemporaryDetach) mPreserveDetachedSelection = false; downgradeEasyCorrectionSpans(); } @@ -2679,6 +2704,7 @@ public class Editor { if (menu.hasVisibleItems() || mode.getCustomView() != null) { getSelectionController().show(); + mTextView.setHasTransientState(true); return true; } else { return false; @@ -2707,7 +2733,17 @@ public class Editor { if (mCustomSelectionActionModeCallback != null) { mCustomSelectionActionModeCallback.onDestroyActionMode(mode); } - Selection.setSelection((Spannable) mTextView.getText(), mTextView.getSelectionEnd()); + + /* + * If we're ending this mode because we're detaching from a window, + * we still have selection state to preserve. Don't clear it, we'll + * bring back the selection mode when (if) we get reattached. + */ + if (!mPreserveDetachedSelection) { + Selection.setSelection((Spannable) mTextView.getText(), + mTextView.getSelectionEnd()); + mTextView.setHasTransientState(false); + } if (mSelectionModifierCursorController != null) { mSelectionModifierCursorController.hide(); diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java index 098a034b2e64..56eca01fb00b 100644 --- a/core/java/android/widget/TextView.java +++ b/core/java/android/widget/TextView.java @@ -7257,10 +7257,9 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener // usually because this instance is an editable field in a list if (!mDispatchTemporaryDetach) mTemporaryDetach = true; - // Because of View recycling in ListView, there is no easy way to know when a TextView with - // selection becomes visible again. Until a better solution is found, stop text selection - // mode (if any) as soon as this TextView is recycled. - if (mEditor != null) mEditor.hideControllers(); + // Tell the editor that we are temporarily detached. It can use this to preserve + // selection state as needed. + if (mEditor != null) mEditor.mTemporaryDetach = true; } @Override @@ -7269,6 +7268,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener // Only track when onStartTemporaryDetach() is called directly, // usually because this instance is an editable field in a list if (!mDispatchTemporaryDetach) mTemporaryDetach = false; + if (mEditor != null) mEditor.mTemporaryDetach = false; } @Override |
