Learn about pointer capture introduced in Android O.
Some apps, such as games, remote desktop, and virtualization clients, greatly benefit from getting control over the mouse pointer. Pointer capture is a new feature in Android O that provides such control by delivering all mouse events to a focused view in your app.
Requesting pointer capture
A view in your app can request pointer capture only when the view hierarchy that
contains it has focus. For this reason, you should request pointer capture when
there's a specific user action on the view, such as during an onClick event, or in the onWindowFocusChanged event handler of
your activity.
To request pointer capture, call the requestPointerCapture() method on the view. The following code example shows how to request pointer capture when the user clicks a view:
@Override
public void onClick(View view) {
view.requestPointerCapture();
}
Once the request to capture the pointer is successful, Android calls
onPointerCaptureChange(true). The system delivers the mouse events to the
focused view in your app as long as it's in the same view hierarchy as the view
that requested the capture. Other apps stop receiving mouse events until the
capture is released, including ACTION_OUTSIDE
events. Android delivers pointer events from sources other than the mouse
normally, but the mouse pointer is not visible anymore.
Handling captured pointer events
Once a view has successfully acquired the pointer capture, Android starts delivering the mouse events. Your focused view can handle the events by performing one of the following tasks:
- If you're using a custom view, override onCapturedPointerEvent(MotionEvent).
- Otherwise, register an OnCapturedPointerListener.
The following code example shows how to implement onCapturedPointerEvent(MotionEvent):
@Override
public boolean onCapturedPointerEvent(MotionEvent motionEvent) {
// Get the coordinates required by your app
float verticalOffset = motionEvent.getY();
// Use the coordinates to update your view and return true if the event was
// successfully processed
return true;
}
The following code example shows how to register an OnCapturedPointerListener:
theView.setOnCapturedPointerListener(new View.OnCapturedPointerListener() {
@Override
public boolean onCapturedPointer (View view, MotionEvent motionEvent) {
// Get the coordinates required by your app
float horizontalOffset = motionEvent.getX();
// Use the coordinates to update your view and return true if the event was
// successfully processed
return true;
}
});
Whether you use a custom view or register a listener, your view receives a
MotionEvent with pointer coordinates that specify relative
movements such as X/Y deltas, similar to the coordinates delivered by a
trackball device. You can retrieve the coordinates by using getX() and getY().
Releasing pointer capture
The view in your app can release the pointer capture by calling releasePointerCapture, as shown in the following code example:
@Override
public void onClick(View view) {
view.releasePointerCapture();
}
The system can take the capture away from the view without you explicitly calling releasePointerCapture, most commonly because the view hierarchy that contains the view that requested capture has lost focus.