Вопрос

When using a modern version of Android --- Honeycomb or later --- there is support for displaying a mouse pointer if the hardware is appropriate. For example, on the ASUS Transformer or Toshiba AC100 notebooks.

Are there any APIs to allow an application running on one of these devices to programmatically change its mouse pointer? (Or to hide the pointer completely while in the application's window.)

Это было полезно?

Решение

This feature was added in Android 7.0. You can choose one of the preset system pointers or make one from a bitmap. You can also hide the pointer.

Android 7.0 documentation: https://developer.android.com/about/versions/nougat/android-7.0#custom_pointer_api

PointerIcon class: https://developer.android.com/reference/android/view/PointerIcon.html

I used this to customize the pointer for a WebView. You'll need to make a class extending the view you want to change the pointer for.

If you use a bitmap drawable you should put it in the proper density folders (drawable-mdpi .. drawable-xxxhdpi.) If you don't the system will scale it automatically and it looks really blurry. The system default pointer seems to be around 18dp.

Example of bitmap:

package com.example.packageName;

import android.annotation.TargetApi;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Build;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.PointerIcon;
import android.webkit.WebView;

public class CustomWebview extends WebView {

    private Bitmap bmCursor;
    private PointerIcon pntCursor;

    public CustomWebview(Context context, AttributeSet attrs) {
        super(context, attrs);
        if (Build.VERSION.SDK_INT >= 24) {
            bmCursor = BitmapFactory.decodeResource(getResources(), R.drawable.cursor);
            pntCursor = PointerIcon.create(bmCursor,0,0);
        }
    }

    @TargetApi(24)
    @Override
    public PointerIcon onResolvePointerIcon(MotionEvent me, int pointerIndex) {
        return pntCursor;
    }
}

Example of system pointer:

package com.example.packageName;

import android.annotation.TargetApi;
import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.PointerIcon;
import android.webkit.WebView;

public class CustomWebview extends WebView {
    Context c;
    public CustomWebview(Context context, AttributeSet attrs) {
        super(context, attrs);
        c = context;
    }

    @TargetApi(24)
    @Override
    public PointerIcon onResolvePointerIcon(MotionEvent me, int pointerIndex) {
        return PointerIcon.getSystemIcon(c, PointerIcon.TYPE_CROSSHAIR);
    }
}

Using PointerIcon.TYPE_NULL will hide the cursor.

Because I used my own class for the WebView, I had to rename it's tag to com.example.packageName.CustomWebview in my layout's xml. Like this.

<?xml version="1.0" encoding="utf-8"?>
<com.example.packageName.CustomWebview xmlns:android="http://schemas.android.com/apk/res/android"
         android:layout_width="match_parent"
         android:layout_height="match_parent"
         android:padding="0px"
         android:layout_margin="0px"
         android:scrollbars="none"
         android:nestedScrollingEnabled="false"
         android:background="@drawable/webview_style"
         android:foreground="@drawable/webview_style"
         android:id="@+id/webGame" />

There's also a view.setPointerIcon(PointerIcon) method, but it doesn't seem to change the pointer for the view permanently.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top