Automated import from //branches/donutburger/...@140714,140714
This commit is contained in:
committed by
The Android Open Source Project
parent
07970839eb
commit
38e98fccfa
@@ -110598,6 +110598,36 @@
|
||||
deprecated="not deprecated"
|
||||
visibility="public"
|
||||
>
|
||||
<method name="getInitialScrollX"
|
||||
return="int"
|
||||
abstract="false"
|
||||
native="false"
|
||||
synchronized="false"
|
||||
static="true"
|
||||
final="false"
|
||||
deprecated="not deprecated"
|
||||
visibility="public"
|
||||
>
|
||||
<parameter name="widget" type="android.widget.TextView">
|
||||
</parameter>
|
||||
<parameter name="buffer" type="android.text.Spannable">
|
||||
</parameter>
|
||||
</method>
|
||||
<method name="getInitialScrollY"
|
||||
return="int"
|
||||
abstract="false"
|
||||
native="false"
|
||||
synchronized="false"
|
||||
static="true"
|
||||
final="false"
|
||||
deprecated="not deprecated"
|
||||
visibility="public"
|
||||
>
|
||||
<parameter name="widget" type="android.widget.TextView">
|
||||
</parameter>
|
||||
<parameter name="buffer" type="android.text.Spannable">
|
||||
</parameter>
|
||||
</method>
|
||||
<method name="onTouchEvent"
|
||||
return="boolean"
|
||||
abstract="false"
|
||||
@@ -157343,6 +157373,17 @@
|
||||
visibility="public"
|
||||
>
|
||||
</method>
|
||||
<method name="moveCursorToVisibleOffset"
|
||||
return="boolean"
|
||||
abstract="false"
|
||||
native="false"
|
||||
synchronized="false"
|
||||
static="false"
|
||||
final="false"
|
||||
deprecated="not deprecated"
|
||||
visibility="public"
|
||||
>
|
||||
</method>
|
||||
<method name="onBeginBatchEdit"
|
||||
return="void"
|
||||
abstract="false"
|
||||
|
||||
@@ -18,6 +18,7 @@ package android.text.method;
|
||||
|
||||
import android.util.Log;
|
||||
import android.view.KeyEvent;
|
||||
import android.graphics.Rect;
|
||||
import android.text.*;
|
||||
import android.widget.TextView;
|
||||
import android.view.View;
|
||||
@@ -202,23 +203,54 @@ implements MovementMethod
|
||||
|
||||
public boolean onTouchEvent(TextView widget, Spannable buffer,
|
||||
MotionEvent event) {
|
||||
int initialScrollX = -1, initialScrollY = -1;
|
||||
if (event.getAction() == MotionEvent.ACTION_UP) {
|
||||
initialScrollX = Touch.getInitialScrollX(widget, buffer);
|
||||
initialScrollY = Touch.getInitialScrollY(widget, buffer);
|
||||
}
|
||||
|
||||
boolean handled = Touch.onTouchEvent(widget, buffer, event);
|
||||
|
||||
if (widget.isFocused() && !widget.didTouchFocusSelect()) {
|
||||
if (event.getAction() == MotionEvent.ACTION_UP) {
|
||||
// If we have scrolled, then the up shouldn't move the cursor,
|
||||
// but we do need to make sure the cursor is still visible at
|
||||
// the current scroll offset to avoid the scroll jumping later
|
||||
// to show it.
|
||||
if ((initialScrollY >= 0 && initialScrollY != widget.getScrollY()) ||
|
||||
(initialScrollX >= 0 && initialScrollX != widget.getScrollX())) {
|
||||
widget.moveCursorToVisibleOffset();
|
||||
return true;
|
||||
}
|
||||
|
||||
int x = (int) event.getX();
|
||||
int y = (int) event.getY();
|
||||
|
||||
x -= widget.getTotalPaddingLeft();
|
||||
y -= widget.getTotalPaddingTop();
|
||||
|
||||
// Clamp the position to inside of the view.
|
||||
if (x < 0) {
|
||||
x = 0;
|
||||
} else if (x >= (widget.getWidth()-widget.getTotalPaddingRight())) {
|
||||
x = widget.getWidth()-widget.getTotalPaddingRight() - 1;
|
||||
}
|
||||
if (y < 0) {
|
||||
y = 0;
|
||||
} else if (y >= (widget.getHeight()-widget.getTotalPaddingBottom())) {
|
||||
y = widget.getHeight()-widget.getTotalPaddingBottom() - 1;
|
||||
}
|
||||
|
||||
x += widget.getScrollX();
|
||||
y += widget.getScrollY();
|
||||
|
||||
Layout layout = widget.getLayout();
|
||||
int line = layout.getLineForVertical(y);
|
||||
|
||||
int off = layout.getOffsetForHorizontal(line, x);
|
||||
|
||||
// XXX should do the same adjust for x as we do for the line.
|
||||
|
||||
boolean cap = (MetaKeyKeyListener.getMetaState(buffer,
|
||||
KeyEvent.META_SHIFT_ON) == 1) ||
|
||||
(MetaKeyKeyListener.getMetaState(buffer,
|
||||
|
||||
@@ -21,7 +21,6 @@ import android.text.NoCopySpan;
|
||||
import android.text.Layout.Alignment;
|
||||
import android.text.Spannable;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.view.ViewConfiguration;
|
||||
import android.widget.TextView;
|
||||
|
||||
@@ -82,8 +81,9 @@ public class Touch {
|
||||
|
||||
switch (event.getAction()) {
|
||||
case MotionEvent.ACTION_DOWN:
|
||||
buffer.setSpan(new DragState(event.getX(), event.getY()),
|
||||
0, 0, Spannable.SPAN_MARK_MARK);
|
||||
buffer.setSpan(new DragState(event.getX(), event.getY(),
|
||||
widget.getScrollX(), widget.getScrollY()),
|
||||
0, 0, Spannable.SPAN_MARK_MARK);
|
||||
return true;
|
||||
|
||||
case MotionEvent.ACTION_UP:
|
||||
@@ -142,15 +142,29 @@ public class Touch {
|
||||
return false;
|
||||
}
|
||||
|
||||
public static int getInitialScrollX(TextView widget, Spannable buffer) {
|
||||
DragState[] ds = buffer.getSpans(0, buffer.length(), DragState.class);
|
||||
return ds.length > 0 ? ds[0].mScrollX : -1;
|
||||
}
|
||||
|
||||
public static int getInitialScrollY(TextView widget, Spannable buffer) {
|
||||
DragState[] ds = buffer.getSpans(0, buffer.length(), DragState.class);
|
||||
return ds.length > 0 ? ds[0].mScrollY : -1;
|
||||
}
|
||||
|
||||
private static class DragState implements NoCopySpan {
|
||||
public float mX;
|
||||
public float mY;
|
||||
public int mScrollX;
|
||||
public int mScrollY;
|
||||
public boolean mFarEnough;
|
||||
public boolean mUsed;
|
||||
|
||||
public DragState(float x, float y) {
|
||||
public DragState(float x, float y, int scrollX, int scrollY) {
|
||||
mX = x;
|
||||
mY = y;
|
||||
mScrollX = scrollX;
|
||||
mScrollY = scrollY;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5421,6 +5421,62 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
|
||||
return changed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Move the cursor, if needed, so that it is at an offset that is visible
|
||||
* to the user. This will not move the cursor if it represents more than
|
||||
* one character (a selection range). This will only work if the
|
||||
* TextView contains spannable text; otherwise it will do nothing.
|
||||
*/
|
||||
public boolean moveCursorToVisibleOffset() {
|
||||
if (!(mText instanceof Spannable)) {
|
||||
return false;
|
||||
}
|
||||
int start = Selection.getSelectionStart(mText);
|
||||
int end = Selection.getSelectionEnd(mText);
|
||||
if (start != end) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// First: make sure the line is visible on screen:
|
||||
|
||||
int line = mLayout.getLineForOffset(start);
|
||||
|
||||
final int top = mLayout.getLineTop(line);
|
||||
final int bottom = mLayout.getLineTop(line+1);
|
||||
final int vspace = mBottom - mTop - getExtendedPaddingTop() - getExtendedPaddingBottom();
|
||||
int vslack = (bottom - top) / 2;
|
||||
if (vslack > vspace / 4)
|
||||
vslack = vspace / 4;
|
||||
final int vs = mScrollY;
|
||||
|
||||
if (top < (vs+vslack)) {
|
||||
line = mLayout.getLineForVertical(vs+vslack+(bottom-top));
|
||||
} else if (bottom > (vspace+vs-vslack)) {
|
||||
line = mLayout.getLineForVertical(vspace+vs-vslack-(bottom-top));
|
||||
}
|
||||
|
||||
// Next: make sure the character is visible on screen:
|
||||
|
||||
final int hspace = mRight - mLeft - getCompoundPaddingLeft() - getCompoundPaddingRight();
|
||||
final int hs = mScrollX;
|
||||
final int leftChar = mLayout.getOffsetForHorizontal(line, hs);
|
||||
final int rightChar = mLayout.getOffsetForHorizontal(line, hspace+hs);
|
||||
|
||||
int newStart = start;
|
||||
if (newStart < leftChar) {
|
||||
newStart = leftChar;
|
||||
} else if (newStart > rightChar) {
|
||||
newStart = rightChar;
|
||||
}
|
||||
|
||||
if (newStart != start) {
|
||||
Selection.setSelection((Spannable)mText, newStart);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void computeScroll() {
|
||||
if (mScroller != null) {
|
||||
|
||||
Reference in New Issue
Block a user