From 1a6c27281b399a971674beac634f3d9a703bdd77 Mon Sep 17 00:00:00 2001 From: Vladislav Kaznacheev Date: Fri, 13 May 2016 15:50:12 -0700 Subject: [PATCH] Show tooltip when mouse is hovering over an ActionMenu item Tooltips are already being shown on long press. This CL invokes the same logic on mouse hover (but with a longer tooltip duration). Bug: 24339237 Change-Id: Icba33b317fe737953c6dace91cfe3539a14a1959 --- .../view/menu/ActionMenuItemView.java | 44 ++++++++++++++++--- 1 file changed, 39 insertions(+), 5 deletions(-) diff --git a/core/java/com/android/internal/view/menu/ActionMenuItemView.java b/core/java/com/android/internal/view/menu/ActionMenuItemView.java index 6989654c57cd9..0bf170e3fd871 100644 --- a/core/java/com/android/internal/view/menu/ActionMenuItemView.java +++ b/core/java/com/android/internal/view/menu/ActionMenuItemView.java @@ -28,7 +28,9 @@ import android.util.AttributeSet; import android.view.Gravity; import android.view.MotionEvent; import android.view.View; +import android.view.ViewConfiguration; import android.view.accessibility.AccessibilityEvent; +import android.view.accessibility.AccessibilityManager; import android.widget.ActionMenuView; import android.widget.ForwardingListener; import android.widget.TextView; @@ -57,6 +59,9 @@ public class ActionMenuItemView extends TextView private static final int MAX_ICON_SIZE = 32; // dp private int mMaxIconSize; + private Toast mTooltip; + private Runnable mShowTooltipRunnable = () -> showTooltip(Toast.LENGTH_LONG); + public ActionMenuItemView(Context context) { this(context, null); } @@ -244,6 +249,7 @@ public class ActionMenuItemView extends TextView @Override public boolean dispatchHoverEvent(MotionEvent event) { + updateTooltip(event); // Don't allow children to hover; we want this to be treated as a single component. return onHoverEvent(event); } @@ -262,6 +268,10 @@ public class ActionMenuItemView extends TextView @Override public boolean onLongClick(View v) { + return showTooltip(Toast.LENGTH_SHORT); + } + + private boolean showTooltip(@Toast.Duration int duration) { if (hasText()) { // Don't show the cheat sheet for items that already show text. return false; @@ -277,23 +287,47 @@ public class ActionMenuItemView extends TextView final int height = getHeight(); final int midy = screenPos[1] + height / 2; int referenceX = screenPos[0] + width / 2; - if (v.getLayoutDirection() == View.LAYOUT_DIRECTION_LTR) { + if (getLayoutDirection() == View.LAYOUT_DIRECTION_LTR) { final int screenWidth = context.getResources().getDisplayMetrics().widthPixels; referenceX = screenWidth - referenceX; // mirror } - Toast cheatSheet = Toast.makeText(context, mItemData.getTitle(), Toast.LENGTH_SHORT); + hideTooltip (); + mTooltip = Toast.makeText(context, mItemData.getTitle(), duration); if (midy < displayFrame.height()) { // Show along the top; follow action buttons - cheatSheet.setGravity(Gravity.TOP | Gravity.END, referenceX, + mTooltip.setGravity(Gravity.TOP | Gravity.END, referenceX, screenPos[1] + height - displayFrame.top); } else { // Show along the bottom center - cheatSheet.setGravity(Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL, 0, height); + mTooltip.setGravity(Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL, 0, height); } - cheatSheet.show(); + mTooltip.show(); return true; } + private void hideTooltip() { + if (mTooltip != null) { + mTooltip.cancel(); + mTooltip = null; + } + getHandler().removeCallbacks(mShowTooltipRunnable); + } + + private void updateTooltip(MotionEvent event) { + AccessibilityManager manager = AccessibilityManager.getInstance(mContext); + if (manager.isEnabled() && manager.isTouchExplorationEnabled()) { + return; + } + + final int action = event.getAction(); + if (action == MotionEvent.ACTION_HOVER_MOVE) { + hideTooltip(); + getHandler().postDelayed(mShowTooltipRunnable, ViewConfiguration.getLongPressTimeout()); + } else if (action == MotionEvent.ACTION_HOVER_EXIT) { + hideTooltip(); + } + } + @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { final boolean textVisible = hasText();