summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--api/current.txt1
-rw-r--r--core/java/android/view/View.java40
-rw-r--r--core/java/android/view/ViewConfiguration.java12
-rw-r--r--core/res/res/values/config.xml4
-rw-r--r--core/res/res/values/symbols.xml1
5 files changed, 55 insertions, 3 deletions
diff --git a/api/current.txt b/api/current.txt
index eec7b5387886..2c353bb0b6ef 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -47010,6 +47010,7 @@ package android.view {
method public int getScaledEdgeSlop();
method public int getScaledFadingEdgeLength();
method public float getScaledHorizontalScrollFactor();
+ method public int getScaledHoverSlop();
method public int getScaledMaximumDrawingCacheSize();
method public int getScaledMaximumFlingVelocity();
method public int getScaledMinimumFlingVelocity();
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 623759e178d8..4d0ba592952b 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -4296,6 +4296,38 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
*/
Runnable mShowTooltipRunnable;
Runnable mHideTooltipRunnable;
+
+ /**
+ * Hover move is ignored if it is within this distance in pixels from the previous one.
+ */
+ int mHoverSlop;
+
+ /**
+ * Update the anchor position if it significantly (that is by at least mHoverSlop)
+ * different from the previously stored position. Ignoring insignificant changes
+ * filters out the jitter which is typical for such input sources as stylus.
+ *
+ * @return True if the position has been updated.
+ */
+ private boolean updateAnchorPos(MotionEvent event) {
+ final int newAnchorX = (int) event.getX();
+ final int newAnchorY = (int) event.getY();
+ if (Math.abs(newAnchorX - mAnchorX) <= mHoverSlop
+ && Math.abs(newAnchorY - mAnchorY) <= mHoverSlop) {
+ return false;
+ }
+ mAnchorX = newAnchorX;
+ mAnchorY = newAnchorY;
+ return true;
+ }
+
+ /**
+ * Clear the anchor position to ensure that the next change is considered significant.
+ */
+ private void clearAnchorPos() {
+ mAnchorX = Integer.MAX_VALUE;
+ mAnchorY = Integer.MAX_VALUE;
+ }
}
TooltipInfo mTooltipInfo;
@@ -26813,6 +26845,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
mTooltipInfo = new TooltipInfo();
mTooltipInfo.mShowTooltipRunnable = this::showHoverTooltip;
mTooltipInfo.mHideTooltipRunnable = this::hideTooltip;
+ mTooltipInfo.mHoverSlop = ViewConfiguration.get(mContext).getScaledHoverSlop();
+ mTooltipInfo.clearAnchorPos();
}
mTooltipInfo.mTooltipText = tooltipText;
}
@@ -26879,6 +26913,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
mTooltipInfo.mTooltipPopup.hide();
mTooltipInfo.mTooltipPopup = null;
mTooltipInfo.mTooltipFromLongClick = false;
+ mTooltipInfo.clearAnchorPos();
if (mAttachInfo != null) {
mAttachInfo.mTooltipHost = null;
}
@@ -26903,11 +26938,9 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
if ((mViewFlags & TOOLTIP) != TOOLTIP || (mViewFlags & ENABLED_MASK) != ENABLED) {
break;
}
- if (!mTooltipInfo.mTooltipFromLongClick) {
+ if (!mTooltipInfo.mTooltipFromLongClick && mTooltipInfo.updateAnchorPos(event)) {
if (mTooltipInfo.mTooltipPopup == null) {
// Schedule showing the tooltip after a timeout.
- mTooltipInfo.mAnchorX = (int) event.getX();
- mTooltipInfo.mAnchorY = (int) event.getY();
removeCallbacks(mTooltipInfo.mShowTooltipRunnable);
postDelayed(mTooltipInfo.mShowTooltipRunnable,
ViewConfiguration.getHoverTooltipShowTimeout());
@@ -26929,6 +26962,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
return true;
case MotionEvent.ACTION_HOVER_EXIT:
+ mTooltipInfo.clearAnchorPos();
if (!mTooltipInfo.mTooltipFromLongClick) {
hideTooltip();
}
diff --git a/core/java/android/view/ViewConfiguration.java b/core/java/android/view/ViewConfiguration.java
index c44c8dda83a9..c5a94daaba53 100644
--- a/core/java/android/view/ViewConfiguration.java
+++ b/core/java/android/view/ViewConfiguration.java
@@ -290,6 +290,7 @@ public class ViewConfiguration {
private final int mMaximumFlingVelocity;
private final int mScrollbarSize;
private final int mTouchSlop;
+ private final int mHoverSlop;
private final int mMinScrollbarTouchTarget;
private final int mDoubleTapTouchSlop;
private final int mPagingTouchSlop;
@@ -320,6 +321,7 @@ public class ViewConfiguration {
mMaximumFlingVelocity = MAXIMUM_FLING_VELOCITY;
mScrollbarSize = SCROLL_BAR_SIZE;
mTouchSlop = TOUCH_SLOP;
+ mHoverSlop = TOUCH_SLOP / 2;
mMinScrollbarTouchTarget = MIN_SCROLLBAR_TOUCH_TARGET;
mDoubleTapTouchSlop = DOUBLE_TAP_TOUCH_SLOP;
mPagingTouchSlop = PAGING_TOUCH_SLOP;
@@ -407,6 +409,8 @@ public class ViewConfiguration {
com.android.internal.R.bool.config_ui_enableFadingMarquee);
mTouchSlop = res.getDimensionPixelSize(
com.android.internal.R.dimen.config_viewConfigurationTouchSlop);
+ mHoverSlop = res.getDimensionPixelSize(
+ com.android.internal.R.dimen.config_viewConfigurationHoverSlop);
mMinScrollbarTouchTarget = res.getDimensionPixelSize(
com.android.internal.R.dimen.config_minScrollbarTouchTarget);
mPagingTouchSlop = mTouchSlop * 2;
@@ -640,6 +644,14 @@ public class ViewConfiguration {
}
/**
+ * @return Distance in pixels a hover can wander while it is still considered "stationary".
+ *
+ */
+ public int getScaledHoverSlop() {
+ return mHoverSlop;
+ }
+
+ /**
* @return Distance in pixels the first touch can wander before we do not consider this a
* potential double tap event
* @hide
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 0b38d1b1fca1..22662e5f43db 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -2061,6 +2061,10 @@
movement threshold where scrolling should begin. -->
<dimen name="config_viewConfigurationTouchSlop">8dp</dimen>
+ <!-- Base "hover slop" value used by ViewConfiguration as a
+ movement threshold under which hover is considered "stationary". -->
+ <dimen name="config_viewConfigurationHoverSlop">4dp</dimen>
+
<!-- Minimum velocity to initiate a fling, as measured in dips per second. -->
<dimen name="config_viewMinFlingVelocity">50dp</dimen>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index f659360199ef..c42ad243e7b9 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -470,6 +470,7 @@
<java-symbol type="dimen" name="config_minScrollbarTouchTarget" />
<java-symbol type="dimen" name="config_prefDialogWidth" />
<java-symbol type="dimen" name="config_viewConfigurationTouchSlop" />
+ <java-symbol type="dimen" name="config_viewConfigurationHoverSlop" />
<java-symbol type="dimen" name="config_viewMinFlingVelocity" />
<java-symbol type="dimen" name="config_viewMaxFlingVelocity" />
<java-symbol type="dimen" name="config_scrollbarSize" />