Merge "Popup windows positions are updated when a TextView is scrolled"
This commit is contained in:
committed by
Android (Google) Code Review
commit
a41bc33855
@@ -9162,6 +9162,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
|
|||||||
startDrag(data, getTextThumbnailBuilder(selectedText), localState, 0);
|
startDrag(data, getTextThumbnailBuilder(selectedText), localState, 0);
|
||||||
stopSelectionActionMode();
|
stopSelectionActionMode();
|
||||||
} else {
|
} else {
|
||||||
|
getSelectionController().hide();
|
||||||
selectCurrentWord();
|
selectCurrentWord();
|
||||||
getSelectionController().show();
|
getSelectionController().show();
|
||||||
}
|
}
|
||||||
@@ -9209,7 +9210,8 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
|
|||||||
}
|
}
|
||||||
|
|
||||||
private interface TextViewPositionListener {
|
private interface TextViewPositionListener {
|
||||||
public void updatePosition(int parentPositionX, int parentPositionY, boolean modified);
|
public void updatePosition(int parentPositionX, int parentPositionY,
|
||||||
|
boolean parentPositionChanged, boolean parentScrolled);
|
||||||
}
|
}
|
||||||
|
|
||||||
private class PositionListener implements ViewTreeObserver.OnPreDrawListener {
|
private class PositionListener implements ViewTreeObserver.OnPreDrawListener {
|
||||||
@@ -9222,6 +9224,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
|
|||||||
// Absolute position of the TextView with respect to its parent window
|
// Absolute position of the TextView with respect to its parent window
|
||||||
private int mPositionX, mPositionY;
|
private int mPositionX, mPositionY;
|
||||||
private int mNumberOfListeners;
|
private int mNumberOfListeners;
|
||||||
|
private boolean mScrollHasChanged;
|
||||||
|
|
||||||
public void addSubscriber(TextViewPositionListener positionListener, boolean canMove) {
|
public void addSubscriber(TextViewPositionListener positionListener, boolean canMove) {
|
||||||
if (mNumberOfListeners == 0) {
|
if (mNumberOfListeners == 0) {
|
||||||
@@ -9273,15 +9276,16 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
|
|||||||
updatePosition();
|
updatePosition();
|
||||||
|
|
||||||
for (int i = 0; i < MAXIMUM_NUMBER_OF_LISTENERS; i++) {
|
for (int i = 0; i < MAXIMUM_NUMBER_OF_LISTENERS; i++) {
|
||||||
if (mPositionHasChanged || mCanMove[i]) {
|
if (mPositionHasChanged || mScrollHasChanged || mCanMove[i]) {
|
||||||
TextViewPositionListener positionListener = mPositionListeners[i];
|
TextViewPositionListener positionListener = mPositionListeners[i];
|
||||||
if (positionListener != null) {
|
if (positionListener != null) {
|
||||||
positionListener.updatePosition(mPositionX, mPositionY,
|
positionListener.updatePosition(mPositionX, mPositionY,
|
||||||
mPositionHasChanged);
|
mPositionHasChanged, mScrollHasChanged);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mScrollHasChanged = false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -9323,6 +9327,18 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
|
|||||||
final int primaryHorizontal = (int) mLayout.getPrimaryHorizontal(offset);
|
final int primaryHorizontal = (int) mLayout.getPrimaryHorizontal(offset);
|
||||||
return isVisible(primaryHorizontal, lineBottom);
|
return isVisible(primaryHorizontal, lineBottom);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void onScrollChanged() {
|
||||||
|
mScrollHasChanged = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onScrollChanged(int horiz, int vert, int oldHoriz, int oldVert) {
|
||||||
|
super.onScrollChanged(horiz, vert, oldHoriz, oldVert);
|
||||||
|
if (mPositionListener != null) {
|
||||||
|
mPositionListener.onScrollChanged();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private abstract class PinnedPopupWindow implements TextViewPositionListener {
|
private abstract class PinnedPopupWindow implements TextViewPositionListener {
|
||||||
@@ -9353,7 +9369,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void show() {
|
public void show() {
|
||||||
TextView.this.getPositionListener().addSubscriber(this, false);
|
TextView.this.getPositionListener().addSubscriber(this, false /* offset is fixed */);
|
||||||
|
|
||||||
computeLocalPosition();
|
computeLocalPosition();
|
||||||
|
|
||||||
@@ -9412,8 +9428,11 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void updatePosition(int parentPositionX, int parentPositionY, boolean modified) {
|
public void updatePosition(int parentPositionX, int parentPositionY,
|
||||||
|
boolean parentPositionChanged, boolean parentScrolled) {
|
||||||
|
// Either parentPositionChanged or parentScrolled is true, check if still visible
|
||||||
if (isShowing() && getPositionListener().isOffsetVisible(getTextOffset())) {
|
if (isShowing() && getPositionListener().isOffsetVisible(getTextOffset())) {
|
||||||
|
if (parentScrolled) computeLocalPosition();
|
||||||
updatePosition(parentPositionX, parentPositionY);
|
updatePosition(parentPositionX, parentPositionY);
|
||||||
} else {
|
} else {
|
||||||
hide();
|
hide();
|
||||||
@@ -10366,7 +10385,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
|
|||||||
|
|
||||||
if (i > 0 && i < iMax &&
|
if (i > 0 && i < iMax &&
|
||||||
(now - mPreviousOffsetsTimes[index]) > TOUCH_UP_FILTER_DELAY_BEFORE) {
|
(now - mPreviousOffsetsTimes[index]) > TOUCH_UP_FILTER_DELAY_BEFORE) {
|
||||||
positionAtCursorOffset(mPreviousOffsets[index]);
|
positionAtCursorOffset(mPreviousOffsets[index], false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -10382,11 +10401,11 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
|
|||||||
public void show() {
|
public void show() {
|
||||||
if (isShowing()) return;
|
if (isShowing()) return;
|
||||||
|
|
||||||
getPositionListener().addSubscriber(this, true);
|
getPositionListener().addSubscriber(this, true /* local position may change */);
|
||||||
|
|
||||||
// Make sure the offset is always considered new, even when focusing at same position
|
// Make sure the offset is always considered new, even when focusing at same position
|
||||||
mPreviousOffset = -1;
|
mPreviousOffset = -1;
|
||||||
positionAtCursorOffset(getCurrentCursorOffset());
|
positionAtCursorOffset(getCurrentCursorOffset(), false);
|
||||||
|
|
||||||
hideActionPopupWindow();
|
hideActionPopupWindow();
|
||||||
}
|
}
|
||||||
@@ -10451,7 +10470,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
|
|||||||
|
|
||||||
public abstract void updatePosition(float x, float y);
|
public abstract void updatePosition(float x, float y);
|
||||||
|
|
||||||
protected void positionAtCursorOffset(int offset) {
|
protected void positionAtCursorOffset(int offset, boolean parentScrolled) {
|
||||||
// A HandleView relies on the layout, which may be nulled by external methods
|
// A HandleView relies on the layout, which may be nulled by external methods
|
||||||
if (mLayout == null) {
|
if (mLayout == null) {
|
||||||
// Will update controllers' state, hiding them and stopping selection mode if needed
|
// Will update controllers' state, hiding them and stopping selection mode if needed
|
||||||
@@ -10459,7 +10478,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (offset != mPreviousOffset) {
|
if (offset != mPreviousOffset || parentScrolled) {
|
||||||
updateSelection(offset);
|
updateSelection(offset);
|
||||||
addPositionToTouchUpFilter(offset);
|
addPositionToTouchUpFilter(offset);
|
||||||
final int line = mLayout.getLineForOffset(offset);
|
final int line = mLayout.getLineForOffset(offset);
|
||||||
@@ -10476,9 +10495,10 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void updatePosition(int parentPositionX, int parentPositionY, boolean modified) {
|
public void updatePosition(int parentPositionX, int parentPositionY,
|
||||||
positionAtCursorOffset(getCurrentCursorOffset());
|
boolean parentPositionChanged, boolean parentScrolled) {
|
||||||
if (modified || mPositionHasChanged) {
|
positionAtCursorOffset(getCurrentCursorOffset(), parentScrolled);
|
||||||
|
if (parentPositionChanged || mPositionHasChanged) {
|
||||||
if (mIsDragging) {
|
if (mIsDragging) {
|
||||||
// Update touchToWindow offset in case of parent scrolling while dragging
|
// Update touchToWindow offset in case of parent scrolling while dragging
|
||||||
if (parentPositionX != mLastParentX || parentPositionY != mLastParentY) {
|
if (parentPositionX != mLastParentX || parentPositionY != mLastParentY) {
|
||||||
@@ -10683,7 +10703,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void updatePosition(float x, float y) {
|
public void updatePosition(float x, float y) {
|
||||||
positionAtCursorOffset(getOffsetForPosition(x, y));
|
positionAtCursorOffset(getOffsetForPosition(x, y), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -10722,17 +10742,13 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void updatePosition(float x, float y) {
|
public void updatePosition(float x, float y) {
|
||||||
final int selectionStart = getSelectionStart();
|
|
||||||
final int selectionEnd = getSelectionEnd();
|
|
||||||
|
|
||||||
int offset = getOffsetForPosition(x, y);
|
int offset = getOffsetForPosition(x, y);
|
||||||
|
|
||||||
// No need to redraw when the offset is unchanged
|
|
||||||
if (offset == selectionStart) return;
|
|
||||||
// Handles can not cross and selection is at least one character
|
// Handles can not cross and selection is at least one character
|
||||||
|
final int selectionEnd = getSelectionEnd();
|
||||||
if (offset >= selectionEnd) offset = selectionEnd - 1;
|
if (offset >= selectionEnd) offset = selectionEnd - 1;
|
||||||
|
|
||||||
positionAtCursorOffset(offset);
|
positionAtCursorOffset(offset, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ActionPopupWindow getActionPopupWindow() {
|
public ActionPopupWindow getActionPopupWindow() {
|
||||||
@@ -10763,17 +10779,13 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void updatePosition(float x, float y) {
|
public void updatePosition(float x, float y) {
|
||||||
final int selectionStart = getSelectionStart();
|
|
||||||
final int selectionEnd = getSelectionEnd();
|
|
||||||
|
|
||||||
int offset = getOffsetForPosition(x, y);
|
int offset = getOffsetForPosition(x, y);
|
||||||
|
|
||||||
// No need to redraw when the offset is unchanged
|
|
||||||
if (offset == selectionEnd) return;
|
|
||||||
// Handles can not cross and selection is at least one character
|
// Handles can not cross and selection is at least one character
|
||||||
|
final int selectionStart = getSelectionStart();
|
||||||
if (offset <= selectionStart) offset = selectionStart + 1;
|
if (offset <= selectionStart) offset = selectionStart + 1;
|
||||||
|
|
||||||
positionAtCursorOffset(offset);
|
positionAtCursorOffset(offset, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setActionPopupWindow(ActionPopupWindow actionPopupWindow) {
|
public void setActionPopupWindow(ActionPopupWindow actionPopupWindow) {
|
||||||
|
|||||||
Reference in New Issue
Block a user