Loading core/java/android/view/View.java +18 −2 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -2691,6 +2692,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 Loading Loading @@ -10676,6 +10683,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); } Loading Loading @@ -11577,6 +11585,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; Loading @@ -11590,6 +11599,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(); } Loading Loading @@ -11654,6 +11664,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) { Loading Loading @@ -11694,6 +11707,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, mInContextButtonPress = false; mHasPerformedLongPress = false; mIgnoreNextUpEvent = false; mPrivateFlags3 &= ~PFLAG3_FINGER_DOWN; break; case MotionEvent.ACTION_MOVE: Loading @@ -11710,6 +11724,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, if ((mPrivateFlags & PFLAG_PRESSED) != 0) { setPressed(false); } mPrivateFlags3 &= ~PFLAG3_FINGER_DOWN; } break; } Loading Loading @@ -24455,7 +24470,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; } core/java/com/android/internal/view/TooltipPopup.java +24 −10 Original line number Diff line number Diff line Loading @@ -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); Loading @@ -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); Loading @@ -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. Loading @@ -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; } } } } core/res/res/layout/tooltip.xml +5 −3 Original line number Diff line number Diff line Loading @@ -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" /> Loading core/res/res/values/dimens.xml +8 −4 Original line number Diff line number Diff line Loading @@ -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> core/res/res/values/symbols.xml +3 −1 Original line number Diff line number Diff line Loading @@ -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" /> Loading Loading
core/java/android/view/View.java +18 −2 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -2691,6 +2692,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 Loading Loading @@ -10676,6 +10683,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); } Loading Loading @@ -11577,6 +11585,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; Loading @@ -11590,6 +11599,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(); } Loading Loading @@ -11654,6 +11664,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) { Loading Loading @@ -11694,6 +11707,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, mInContextButtonPress = false; mHasPerformedLongPress = false; mIgnoreNextUpEvent = false; mPrivateFlags3 &= ~PFLAG3_FINGER_DOWN; break; case MotionEvent.ACTION_MOVE: Loading @@ -11710,6 +11724,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, if ((mPrivateFlags & PFLAG_PRESSED) != 0) { setPressed(false); } mPrivateFlags3 &= ~PFLAG3_FINGER_DOWN; } break; } Loading Loading @@ -24455,7 +24470,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; }
core/java/com/android/internal/view/TooltipPopup.java +24 −10 Original line number Diff line number Diff line Loading @@ -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); Loading @@ -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); Loading @@ -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. Loading @@ -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; } } } }
core/res/res/layout/tooltip.xml +5 −3 Original line number Diff line number Diff line Loading @@ -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" /> Loading
core/res/res/values/dimens.xml +8 −4 Original line number Diff line number Diff line Loading @@ -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>
core/res/res/values/symbols.xml +3 −1 Original line number Diff line number Diff line Loading @@ -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" /> Loading