summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/android/widget/TextView.java118
1 files changed, 54 insertions, 64 deletions
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 766b520f2b40..aae38090e8e1 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -16,11 +16,6 @@
package android.widget;
-import com.android.internal.util.FastMath;
-import com.android.internal.widget.EditableInputConnection;
-
-import org.xmlpull.v1.XmlPullParserException;
-
import android.R;
import android.content.ClipData;
import android.content.ClipData.Item;
@@ -132,6 +127,11 @@ import android.view.inputmethod.InputConnection;
import android.view.inputmethod.InputMethodManager;
import android.widget.RemoteViews.RemoteView;
+import com.android.internal.util.FastMath;
+import com.android.internal.widget.EditableInputConnection;
+
+import org.xmlpull.v1.XmlPullParserException;
+
import java.io.IOException;
import java.lang.ref.WeakReference;
import java.text.BreakIterator;
@@ -1119,6 +1119,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
}
}
super.setEnabled(enabled);
+ prepareCursorControllers();
}
/**
@@ -2841,8 +2842,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
// Do not change the movement method for text that support text selection as it
// would prevent an arbitrary cursor displacement.
- final boolean hasTextSelection = this instanceof EditText || mTextIsSelectable;
- if (mLinksClickable && !hasTextSelection) {
+ if (mLinksClickable && !textCanBeSelected()) {
setMovementMethod(LinkMovementMethod.getInstance());
}
}
@@ -4228,7 +4228,9 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
* {@link android.R.styleable#TextView_textIsSelectable} XML attribute to make this TextView
* selectable (text is not selectable by default).
*
- * Note that the content of an EditText is always selectable.
+ * Note that this method simply returns the state of this flag. Although this flag has to be set
+ * in order to select text in non-editable TextView, the content of an {@link EditText} can
+ * always be selected, independently of the value of this flag.
*
* @return True if the text displayed in this TextView can be selected by the user.
*
@@ -4465,12 +4467,12 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
selStart = getSelectionStart();
selEnd = getSelectionEnd();
- if ((isCursorVisible() || mTextIsSelectable) && selStart >= 0 && isEnabled()) {
+ if (selStart >= 0) {
if (mHighlightPath == null)
mHighlightPath = new Path();
if (selStart == selEnd) {
- if (!mTextIsSelectable &&
+ if (isCursorVisible() &&
(SystemClock.uptimeMillis() - mShowCursor) % (2 * BLINK) < BLINK) {
if (mHighlightPathBogus) {
mHighlightPath.reset();
@@ -4489,7 +4491,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
highlight = mHighlightPath;
drawCursor = mCursorCount > 0;
}
- } else {
+ } else if (textCanBeSelected()) {
if (mHighlightPathBogus) {
mHighlightPath.reset();
mLayout.getSelectionPath(selStart, selEnd, mHighlightPath);
@@ -7450,9 +7452,6 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
public boolean onTouchEvent(MotionEvent event) {
final int action = event.getActionMasked();
- if (hasInsertionController()) {
- getInsertionController().onTouchEvent(event);
- }
if (hasSelectionController()) {
getSelectionController().onTouchEvent(event);
}
@@ -7880,7 +7879,8 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
// prepareCursorController() relies on this method.
// If you change this condition, make sure prepareCursorController is called anywhere
// the value of this condition might be changed.
- return mText instanceof Spannable && mMovement != null && mMovement.canSelectArbitrarily();
+ if (mMovement == null || !mMovement.canSelectArbitrarily()) return false;
+ return isTextEditable() || (mTextIsSelectable && mText instanceof Spannable && isEnabled());
}
private boolean canCut() {
@@ -7968,6 +7968,10 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
final int minOffset = extractRangeStartFromLong(lastTouchOffsets);
final int maxOffset = extractRangeEndFromLong(lastTouchOffsets);
+ // Safety check in case standard touch event handling has been bypassed
+ if (minOffset < 0 || minOffset >= mText.length()) return false;
+ if (maxOffset < 0 || maxOffset >= mText.length()) return false;
+
int selectionStart, selectionEnd;
// If a URLSpan (web address, email, phone...) is found at that position, select it.
@@ -9723,13 +9727,6 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
public void hide();
/**
- * This method is called by {@link #onTouchEvent(MotionEvent)} and gives the controller
- * a chance to become active and/or visible.
- * @param event The touch event
- */
- public boolean onTouchEvent(MotionEvent event);
-
- /**
* Called when the view is detached from window. Perform house keeping task, such as
* stopping Runnable thread that would otherwise keep a reference on the context, thus
* preventing the activity from being recycled.
@@ -9756,10 +9753,6 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
}
}
- public boolean onTouchEvent(MotionEvent ev) {
- return false;
- }
-
public void onTouchModeChanged(boolean isInTouchMode) {
if (!isInTouchMode) {
hide();
@@ -9818,52 +9811,49 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
if (mEndHandle != null) mEndHandle.hide();
}
- public boolean onTouchEvent(MotionEvent event) {
+ public void onTouchEvent(MotionEvent event) {
// This is done even when the View does not have focus, so that long presses can start
// selection and tap can move cursor from this tap position.
- if (isTextEditable() || mTextIsSelectable) {
- switch (event.getActionMasked()) {
- case MotionEvent.ACTION_DOWN:
- final float x = event.getX();
- final float y = event.getY();
-
- // Remember finger down position, to be able to start selection from there
- mMinTouchOffset = mMaxTouchOffset = getOffsetForPosition(x, y);
-
- // Double tap detection
- long duration = SystemClock.uptimeMillis() - mPreviousTapUpTime;
- if (duration <= ViewConfiguration.getDoubleTapTimeout() &&
- isPositionOnText(x, y)) {
- final float deltaX = x - mPreviousTapPositionX;
- final float deltaY = y - mPreviousTapPositionY;
- final float distanceSquared = deltaX * deltaX + deltaY * deltaY;
- if (distanceSquared < mSquaredTouchSlopDistance) {
- showSuggestions();
- mDiscardNextActionUp = true;
- }
+ switch (event.getActionMasked()) {
+ case MotionEvent.ACTION_DOWN:
+ final float x = event.getX();
+ final float y = event.getY();
+
+ // Remember finger down position, to be able to start selection from there
+ mMinTouchOffset = mMaxTouchOffset = getOffsetForPosition(x, y);
+
+ // Double tap detection
+ long duration = SystemClock.uptimeMillis() - mPreviousTapUpTime;
+ if (duration <= ViewConfiguration.getDoubleTapTimeout() &&
+ isPositionOnText(x, y)) {
+ final float deltaX = x - mPreviousTapPositionX;
+ final float deltaY = y - mPreviousTapPositionY;
+ final float distanceSquared = deltaX * deltaX + deltaY * deltaY;
+ if (distanceSquared < mSquaredTouchSlopDistance) {
+ showSuggestions();
+ mDiscardNextActionUp = true;
}
+ }
- mPreviousTapPositionX = x;
- mPreviousTapPositionY = y;
+ mPreviousTapPositionX = x;
+ mPreviousTapPositionY = y;
- break;
+ break;
- case MotionEvent.ACTION_POINTER_DOWN:
- case MotionEvent.ACTION_POINTER_UP:
- // Handle multi-point gestures. Keep min and max offset positions.
- // Only activated for devices that correctly handle multi-touch.
- if (mContext.getPackageManager().hasSystemFeature(
- PackageManager.FEATURE_TOUCHSCREEN_MULTITOUCH_DISTINCT)) {
- updateMinAndMaxOffsets(event);
- }
- break;
+ case MotionEvent.ACTION_POINTER_DOWN:
+ case MotionEvent.ACTION_POINTER_UP:
+ // Handle multi-point gestures. Keep min and max offset positions.
+ // Only activated for devices that correctly handle multi-touch.
+ if (mContext.getPackageManager().hasSystemFeature(
+ PackageManager.FEATURE_TOUCHSCREEN_MULTITOUCH_DISTINCT)) {
+ updateMinAndMaxOffsets(event);
+ }
+ break;
- case MotionEvent.ACTION_UP:
- mPreviousTapUpTime = SystemClock.uptimeMillis();
- break;
- }
+ case MotionEvent.ACTION_UP:
+ mPreviousTapUpTime = SystemClock.uptimeMillis();
+ break;
}
- return false;
}
/**