diff --git a/core/java/android/view/PointerIcon.java b/core/java/android/view/PointerIcon.java index 6a493e6c6ff1c..d88994b7296e9 100644 --- a/core/java/android/view/PointerIcon.java +++ b/core/java/android/view/PointerIcon.java @@ -57,8 +57,9 @@ public final class PointerIcon implements Parcelable { /** Type constant: Null icon. It has no bitmap. */ public static final int TYPE_NULL = 0; - /** Type constant: no icons are specified. If all views uses this, then falls back - * to the default type, but this is helpful to distinguish a view explicitly want + /** + * Type constant: no icons are specified. If all views uses this, then the pointer icon falls + * back to the default type, but this is helpful to distinguish a view that explicitly wants * to have the default icon. * @hide */ diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java index 6cd894113ca68..003307db832a5 100644 --- a/core/java/android/view/View.java +++ b/core/java/android/view/View.java @@ -92,6 +92,7 @@ import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.Drawable; import android.graphics.drawable.GradientDrawable; import android.hardware.display.DisplayManagerGlobal; +import android.hardware.input.InputManager; import android.net.Uri; import android.os.Build; import android.os.Bundle; @@ -5413,7 +5414,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, /** * The pointer icon when the mouse hovers on this view. The default is null. */ - private PointerIcon mPointerIcon; + private PointerIcon mMousePointerIcon; /** * @hide @@ -29506,30 +29507,71 @@ public class View implements Drawable.Callback, KeyEvent.Callback, } /** - * Returns the pointer icon for the motion event, or null if it doesn't specify the icon. - * The default implementation does not care the location or event types, but some subclasses - * may use it (such as WebViews). - * @param event The MotionEvent from a mouse - * @param pointerIndex The index of the pointer for which to retrieve the {@link PointerIcon}. - * This will be between 0 and {@link MotionEvent#getPointerCount()}. + * Resolve the pointer icon that should be used for specified pointer in the motion event. + * + * The default implementation will resolve the pointer icon to one set using + * {@link #setPointerIcon(PointerIcon)} for mouse devices. Subclasses may override this to + * customize the icon for the given pointer. + * + * For example, the pointer icon for a stylus pointer can be resolved in the following way: + *
+     * @Override
+     * public PointerIcon onResolvePointerIcon(MotionEvent event, int pointerIndex) {
+     *     final int toolType = event.getToolType(pointerIndex);
+     *     if (!event.isFromSource(InputDevice.SOURCE_MOUSE)
+     *             && event.isFromSource(InputDevice.SOURCE_STYLUS)
+     *             && (toolType == MotionEvent.TOOL_TYPE_STYLUS
+     *                     || toolType == MotionEvent.TOOL_TYPE_ERASER)) {
+     *         // Show this pointer icon only if this pointer is a stylus.
+     *         return PointerIcon.getSystemIcon(mContext, PointerIcon.TYPE_WAIT);
+     *     }
+     *     // Use the default logic for determining the pointer icon for other non-stylus pointers,
+     *     // like for the mouse cursor.
+     *     return super.onResolvePointerIcon(event, pointerIndex);
+     * }
+     * 
+ * + * @param event The {@link MotionEvent} that requires a pointer icon to be resolved for one of + * pointers. + * @param pointerIndex The index of the pointer in {@code event} for which to retrieve the + * {@link PointerIcon}. This will be between 0 and {@link MotionEvent#getPointerCount()}. + * @return the pointer icon to use for specified pointer, or {@code null} if a pointer icon + * is not specified and the default icon should be used. * @see PointerIcon + * @see InputManager#isStylusPointerIconEnabled() */ public PointerIcon onResolvePointerIcon(MotionEvent event, int pointerIndex) { final float x = event.getX(pointerIndex); final float y = event.getY(pointerIndex); if (isDraggingScrollBar() || isOnScrollbarThumb(x, y)) { - return PointerIcon.getSystemIcon(mContext, PointerIcon.TYPE_ARROW); + // Use the default pointer icon. + return null; } - return mPointerIcon; + + // Note: A drawing tablet will have both SOURCE_MOUSE and SOURCE_STYLUS, but it would use + // TOOL_TYPE_STYLUS. For now, treat drawing tablets the same way as a mouse or touchpad. + if (event.isFromSource(InputDevice.SOURCE_MOUSE)) { + return mMousePointerIcon; + } + + return null; } /** - * Set the pointer icon for the current view. + * Set the pointer icon to be used for a mouse pointer in the current view. + * * Passing {@code null} will restore the pointer icon to its default value. + * Note that setting the pointer icon using this method will only set it for events coming from + * a mouse device (i.e. with source {@link InputDevice#SOURCE_MOUSE}). To resolve + * the pointer icon for other device types like styluses, override + * {@link #onResolvePointerIcon(MotionEvent, int)}. + * * @param pointerIcon A PointerIcon instance which will be shown when the mouse hovers. + * @see #onResolvePointerIcon(MotionEvent, int) + * @see PointerIcon */ public void setPointerIcon(PointerIcon pointerIcon) { - mPointerIcon = pointerIcon; + mMousePointerIcon = pointerIcon; if (mAttachInfo == null || mAttachInfo.mHandlingPointerEvent) { return; } @@ -29540,11 +29582,13 @@ public class View implements Drawable.Callback, KeyEvent.Callback, } /** - * Gets the pointer icon for the current view. + * Gets the mouse pointer icon for the current view. + * + * @see #setPointerIcon(PointerIcon) */ @InspectableProperty public PointerIcon getPointerIcon() { - return mPointerIcon; + return mMousePointerIcon; } /**