summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/android/view/View.java20
-rw-r--r--core/java/com/android/internal/view/TooltipPopup.java34
-rw-r--r--core/res/res/layout/tooltip.xml8
-rw-r--r--core/res/res/values/dimens.xml12
-rw-r--r--core/res/res/values/symbols.xml4
5 files changed, 58 insertions, 20 deletions
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 12658bd8f0ce..5f7c9dab9768 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -2477,7 +2477,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
* 1 PFLAG3_ASSIST_BLOCKED
* 1 PFLAG3_CLUSTER
* 1 PFLAG3_SECTION
- * xxxxxx * NO LONGER NEEDED, SHOULD BE REUSED *
+ * 1 PFLAG3_FINGER_DOWN
+ * xxxxx * NO LONGER NEEDED, SHOULD BE REUSED *
* 1 PFLAG3_OVERLAPPING_RENDERING_FORCED_VALUE
* 1 PFLAG3_HAS_OVERLAPPING_RENDERING_FORCED
* 1 PFLAG3_TEMPORARY_DETACH
@@ -2692,6 +2693,12 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
private static final int PFLAG3_SECTION = 0x10000;
/**
+ * Indicates that the user is currently touching the screen.
+ * Currently used for the tooltip positioning only.
+ */
+ private static final int PFLAG3_FINGER_DOWN = 0x20000;
+
+ /**
* Whether this view has rendered elements that overlap (see {@link
* #hasOverlappingRendering()}, {@link #forceHasOverlappingRendering(boolean)}, and
* {@link #getHasOverlappingRendering()} ). The value in this bit is only valid when
@@ -10661,6 +10668,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
if (isPressed()) {
setPressed(false);
}
+ mPrivateFlags3 &= ~PFLAG3_FINGER_DOWN;
if (imm != null && (mPrivateFlags & PFLAG_FOCUSED) != 0) {
imm.focusOut(this);
}
@@ -11562,6 +11570,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
if (action == MotionEvent.ACTION_UP && (mPrivateFlags & PFLAG_PRESSED) != 0) {
setPressed(false);
}
+ mPrivateFlags3 &= ~PFLAG3_FINGER_DOWN;
// A disabled view that is clickable still consumes the touch
// events, it just doesn't respond to them.
return clickable;
@@ -11575,6 +11584,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
if (clickable || (viewFlags & TOOLTIP) == TOOLTIP) {
switch (action) {
case MotionEvent.ACTION_UP:
+ mPrivateFlags3 &= ~PFLAG3_FINGER_DOWN;
if ((viewFlags & TOOLTIP) == TOOLTIP) {
handleTooltipUp();
}
@@ -11639,6 +11649,9 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
break;
case MotionEvent.ACTION_DOWN:
+ if (event.getSource() == InputDevice.SOURCE_TOUCHSCREEN) {
+ mPrivateFlags3 |= PFLAG3_FINGER_DOWN;
+ }
mHasPerformedLongPress = false;
if (!clickable) {
@@ -11679,6 +11692,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
mInContextButtonPress = false;
mHasPerformedLongPress = false;
mIgnoreNextUpEvent = false;
+ mPrivateFlags3 &= ~PFLAG3_FINGER_DOWN;
break;
case MotionEvent.ACTION_MOVE:
@@ -11695,6 +11709,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
if ((mPrivateFlags & PFLAG_PRESSED) != 0) {
setPressed(false);
}
+ mPrivateFlags3 &= ~PFLAG3_FINGER_DOWN;
}
break;
}
@@ -24440,7 +24455,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
hideTooltip();
mTooltipInfo.mTooltipFromLongClick = fromLongClick;
mTooltipInfo.mTooltipPopup = new TooltipPopup(getContext());
- mTooltipInfo.mTooltipPopup.show(this, x, y, tooltipText);
+ final boolean fromTouch = (mPrivateFlags3 & PFLAG3_FINGER_DOWN) == PFLAG3_FINGER_DOWN;
+ mTooltipInfo.mTooltipPopup.show(this, x, y, fromTouch, tooltipText);
mAttachInfo.mTooltipHost = this;
return true;
}
diff --git a/core/java/com/android/internal/view/TooltipPopup.java b/core/java/com/android/internal/view/TooltipPopup.java
index 4f48b9645c69..c5f6356e92b1 100644
--- a/core/java/com/android/internal/view/TooltipPopup.java
+++ b/core/java/com/android/internal/view/TooltipPopup.java
@@ -55,14 +55,15 @@ public class TooltipPopup {
| WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
}
- public void show(View anchorView, int anchorX, int anchorY, CharSequence tooltipText) {
+ public void show(View anchorView, int anchorX, int anchorY, boolean fromTouch,
+ CharSequence tooltipText) {
if (isShowing()) {
hide();
}
mMessageView.setText(tooltipText);
- computePosition(anchorView, anchorX, anchorY, mLayoutParams);
+ computePosition(anchorView, anchorX, anchorY, fromTouch, mLayoutParams);
WindowManager wm = (WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE);
wm.addView(mContentView, mLayoutParams);
@@ -89,7 +90,7 @@ public class TooltipPopup {
mMessageView.setText(tooltipText);
}
- private void computePosition(View anchorView, int anchorX, int anchorY,
+ private void computePosition(View anchorView, int anchorX, int anchorY, boolean fromTouch,
WindowManager.LayoutParams outParams) {
final int tooltipPreciseAnchorThreshold = mContext.getResources().getDimensionPixelOffset(
com.android.internal.R.dimen.tooltip_precise_anchor_threshold);
@@ -107,8 +108,10 @@ public class TooltipPopup {
final int offsetAbove;
if (anchorView.getHeight() >= tooltipPreciseAnchorThreshold) {
// Tall view. Align the tooltip vertically to the precise Y position.
- offsetBelow = anchorY;
- offsetAbove = anchorY;
+ final int offsetExtra = mContext.getResources().getDimensionPixelOffset(
+ com.android.internal.R.dimen.tooltip_precise_anchor_extra_offset);
+ offsetBelow = anchorY + offsetExtra;
+ offsetAbove = anchorY - offsetExtra;
} else {
// Otherwise anchor the tooltip to the view center.
offsetBelow = anchorView.getHeight(); // Place below the view in most cases.
@@ -118,20 +121,31 @@ public class TooltipPopup {
outParams.gravity = Gravity.CENTER_HORIZONTAL | Gravity.TOP;
final int tooltipOffset = mContext.getResources().getDimensionPixelOffset(
- com.android.internal.R.dimen.tooltip_y_offset);
+ fromTouch ? com.android.internal.R.dimen.tooltip_y_offset_touch
+ : com.android.internal.R.dimen.tooltip_y_offset_non_touch);
anchorView.getWindowVisibleDisplayFrame(mTmpDisplayFrame);
anchorView.getLocationInWindow(mTmpAnchorPos);
outParams.x = mTmpAnchorPos[0] + offsetX - mTmpDisplayFrame.width() / 2;
- outParams.y = mTmpAnchorPos[1] + offsetBelow + tooltipOffset;
final int spec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
mContentView.measure(spec, spec);
final int tooltipHeight = mContentView.getMeasuredHeight();
- if (outParams.y + tooltipHeight > mTmpDisplayFrame.height()) {
- // The tooltip does not fit below the anchor point, show above instead.
- outParams.y = mTmpAnchorPos[1] + offsetAbove - (tooltipOffset + tooltipHeight);
+ final int yAbove = mTmpAnchorPos[1] + offsetAbove - tooltipOffset - tooltipHeight;
+ final int yBelow = mTmpAnchorPos[1] + offsetBelow + tooltipOffset;
+ if (fromTouch) {
+ if (yAbove >= 0) {
+ outParams.y = yAbove;
+ } else {
+ outParams.y = yBelow;
+ }
+ } else {
+ if (yBelow + tooltipHeight <= mTmpDisplayFrame.height()) {
+ outParams.y = yBelow;
+ } else {
+ outParams.y = yAbove;
+ }
}
}
}
diff --git a/core/res/res/layout/tooltip.xml b/core/res/res/layout/tooltip.xml
index 0aa6a8781d91..376c5eb125f4 100644
--- a/core/res/res/layout/tooltip.xml
+++ b/core/res/res/layout/tooltip.xml
@@ -25,15 +25,17 @@
<TextView
android:id="@android:id/message"
android:layout_width="wrap_content"
- android:layout_height="@dimen/tooltip_height"
+ android:layout_height="wrap_content"
android:layout_margin="@dimen/tooltip_margin"
android:paddingStart="@dimen/tooltip_horizontal_padding"
android:paddingEnd="@dimen/tooltip_horizontal_padding"
- android:gravity="center"
+ android:paddingTop="@dimen/tooltip_vertical_padding"
+ android:paddingBottom="@dimen/tooltip_vertical_padding"
+ android:maxWidth="256dp"
android:background="?android:attr/tooltipFrameBackground"
android:textAppearance="@style/TextAppearance.Tooltip"
android:textColor="?android:attr/tooltipForegroundColor"
- android:singleLine="true"
+ android:maxLines="3"
android:ellipsize="end"
/>
diff --git a/core/res/res/values/dimens.xml b/core/res/res/values/dimens.xml
index 5efa55ca1138..e3b7f02c35da 100644
--- a/core/res/res/values/dimens.xml
+++ b/core/res/res/values/dimens.xml
@@ -489,17 +489,21 @@
<dimen name="cascading_menus_min_smallest_width">720dp</dimen>
<!-- Tooltip dimensions. -->
- <!-- Vertical offset from the edge of the anchor view. -->
- <dimen name="tooltip_y_offset">20dp</dimen>
- <!-- Height of the tooltip. -->
- <dimen name="tooltip_height">32dp</dimen>
+ <!-- Vertical offset from the edge of the anchor view for a touch-triggered tooltip. -->
+ <dimen name="tooltip_y_offset_touch">16dp</dimen>
+ <!-- Vertical offset from the edge of the anchor view for a non-touch-triggered tooltip. -->
+ <dimen name="tooltip_y_offset_non_touch">0dp</dimen>
<!-- The tooltip does not get closer than this to the window edge -->
<dimen name="tooltip_margin">8dp</dimen>
<!-- Left/right padding of the tooltip text. -->
<dimen name="tooltip_horizontal_padding">16dp</dimen>
+ <!-- Top/bottom padding of the tooltip text. -->
+ <dimen name="tooltip_vertical_padding">6.5dp</dimen>
<!-- Border corner radius of the tooltip window. -->
<dimen name="tooltip_corner_radius">2dp</dimen>
<!-- View with the height equal or above this threshold will have a tooltip anchored
to the mouse/touch position -->
<dimen name="tooltip_precise_anchor_threshold">96dp</dimen>
+ <!-- Extra tooltip offset used when anchoring to the mouse/touch position -->
+ <dimen name="tooltip_precise_anchor_extra_offset">8dp</dimen>
</resources>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index ac502e0f803b..989a79db7837 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -437,7 +437,9 @@
<java-symbol type="dimen" name="textview_error_popup_default_width" />
<java-symbol type="dimen" name="toast_y_offset" />
<java-symbol type="dimen" name="tooltip_precise_anchor_threshold" />
- <java-symbol type="dimen" name="tooltip_y_offset" />
+ <java-symbol type="dimen" name="tooltip_precise_anchor_extra_offset" />
+ <java-symbol type="dimen" name="tooltip_y_offset_touch" />
+ <java-symbol type="dimen" name="tooltip_y_offset_non_touch" />
<java-symbol type="dimen" name="action_bar_stacked_max_height" />
<java-symbol type="dimen" name="action_bar_stacked_tab_max_width" />
<java-symbol type="dimen" name="notification_text_size" />