简体   繁体   中英

How to programmatically include the mouse cursor in android tv

I use Webview, which loads random sites. For good navigation I need to turn on the mouse cursor, which will be controlled by D-pad, but I did not find information on how to do it, maybe someone can have developed such navigation, I will be grateful for any help.

Use 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:

To Enable cursor pointer in android tv webview by creating custom pointer layout

public class CursorLayout extends FrameLayout {
public static final int CURSOR_DISAPPEAR_TIMEOUT = 5000;
public static int CURSOR_RADIUS = 0;
public static float CURSOR_STROKE_WIDTH = 0.0f;
public static float MAX_CURSOR_SPEED = 0.0f;
public static int SCROLL_START_PADDING = 100;
public static final int UNCHANGED = -100;
public int EFFECT_DIAMETER;
public int EFFECT_RADIUS;
private Callback callback;
/* access modifiers changed from: private */
public Point cursorDirection = new Point(0, 0);
/* access modifiers changed from: private */
public Runnable cursorHideRunnable = new Runnable() {
    public void run() {
        CursorLayout.this.invalidate();
    }
};
/* access modifiers changed from: private */
public PointF cursorPosition = new PointF(0.0f, 0.0f);
/* access modifiers changed from: private */
public PointF cursorSpeed = new PointF(0.0f, 0.0f);
private Runnable cursorUpdateRunnable = new Runnable() {
    public void run() {
        if (CursorLayout.this.getHandler() != null) {
            CursorLayout.this.getHandler().removeCallbacks(CursorLayout.this.cursorHideRunnable);
        }
        long currentTimeMillis = System.currentTimeMillis();
        long access$100 = currentTimeMillis - CursorLayout.this.lastCursorUpdate;
        CursorLayout.this.lastCursorUpdate = currentTimeMillis;
        float f = ((float) access$100) * 0.05f;
        PointF access$200 = CursorLayout.this.cursorSpeed;
        CursorLayout cursorLayout = CursorLayout.this;
        float f2 = cursorLayout.cursorSpeed.x;
        CursorLayout cursorLayout2 = CursorLayout.this;
        float access$400 = cursorLayout.bound(f2 + (cursorLayout2.bound((float) cursorLayout2.cursorDirection.x, 1.0f) * f), CursorLayout.MAX_CURSOR_SPEED);
        CursorLayout cursorLayout3 = CursorLayout.this;
        float f3 = cursorLayout3.cursorSpeed.y;
        CursorLayout cursorLayout4 = CursorLayout.this;
        access$200.set(access$400, cursorLayout3.bound(f3 + (cursorLayout4.bound((float) cursorLayout4.cursorDirection.y, 1.0f) * f), CursorLayout.MAX_CURSOR_SPEED));
        if (Math.abs(CursorLayout.this.cursorSpeed.x) < 0.1f) {
            CursorLayout.this.cursorSpeed.x = 0.0f;
        }
        if (Math.abs(CursorLayout.this.cursorSpeed.y) < 0.1f) {
            CursorLayout.this.cursorSpeed.y = 0.0f;
        }
        if (CursorLayout.this.cursorDirection.x == 0 && CursorLayout.this.cursorDirection.y == 0 && CursorLayout.this.cursorSpeed.x == 0.0f && CursorLayout.this.cursorSpeed.y == 0.0f) {
            if (CursorLayout.this.getHandler() != null) {
                CursorLayout.this.getHandler().postDelayed(CursorLayout.this.cursorHideRunnable, 5000);
            }
            return;
        }
        CursorLayout.this.tmpPointF.set(CursorLayout.this.cursorPosition);
        CursorLayout.this.cursorPosition.offset(CursorLayout.this.cursorSpeed.x, CursorLayout.this.cursorSpeed.y);
        Log.d("cursor1234_xxxx", String.valueOf(CursorLayout.this.cursorPosition.x));
        Log.d("cursor1234_yyyy", String.valueOf(CursorLayout.this.cursorPosition.y));
        if (CursorLayout.this.cursorPosition.x < 0.0f) {
            CursorLayout.this.cursorPosition.x = 0.0f;
        } else if (CursorLayout.this.cursorPosition.x > ((float) (CursorLayout.this.getWidth() - 1))) {
            CursorLayout.this.cursorPosition.x = (float) (CursorLayout.this.getWidth() - 1);
        }
        if (CursorLayout.this.cursorPosition.y < 0.0f) {
            CursorLayout.this.cursorPosition.y = 0.0f;
        } else if (CursorLayout.this.cursorPosition.y > ((float) (CursorLayout.this.getHeight() - 1))) {
            CursorLayout.this.cursorPosition.y = (float) (CursorLayout.this.getHeight() - 1);
        }
        if (!CursorLayout.this.tmpPointF.equals(CursorLayout.this.cursorPosition) && CursorLayout.this.dpadCenterPressed) {
            CursorLayout cursorLayout5 = CursorLayout.this;
            cursorLayout5.dispatchMotionEvent(cursorLayout5.cursorPosition.x, CursorLayout.this.cursorPosition.y, 2);
        }
        View childAt = CursorLayout.this.getChildAt(0);
        if (childAt != null) {
            if (CursorLayout.this.cursorPosition.y > ((float) (CursorLayout.this.getHeight() - CursorLayout.SCROLL_START_PADDING))) {
                if (CursorLayout.this.cursorSpeed.y > 0.0f && childAt.canScrollVertically((int) CursorLayout.this.cursorSpeed.y)) {
                    childAt.scrollTo(childAt.getScrollX(), childAt.getScrollY() + ((int) CursorLayout.this.cursorSpeed.y));
                }
            } else if (CursorLayout.this.cursorPosition.y < ((float) CursorLayout.SCROLL_START_PADDING) && CursorLayout.this.cursorSpeed.y < 0.0f && childAt.canScrollVertically((int) CursorLayout.this.cursorSpeed.y)) {
                childAt.scrollTo(childAt.getScrollX(), childAt.getScrollY() + ((int) CursorLayout.this.cursorSpeed.y));
            }
            if (CursorLayout.this.cursorPosition.x > ((float) (CursorLayout.this.getWidth() - CursorLayout.SCROLL_START_PADDING))) {
                if (CursorLayout.this.cursorSpeed.x > 0.0f && childAt.canScrollHorizontally((int) CursorLayout.this.cursorSpeed.x)) {
                    childAt.scrollTo(childAt.getScrollX() + ((int) CursorLayout.this.cursorSpeed.x), childAt.getScrollY());
                }
            } else if (CursorLayout.this.cursorPosition.x < ((float) CursorLayout.SCROLL_START_PADDING) && CursorLayout.this.cursorSpeed.x < 0.0f && childAt.canScrollHorizontally((int) CursorLayout.this.cursorSpeed.x)) {
                childAt.scrollTo(childAt.getScrollX() + ((int) CursorLayout.this.cursorSpeed.x), childAt.getScrollY());
            }
        }
        CursorLayout.this.invalidate();
        if (CursorLayout.this.getHandler() != null) {
            CursorLayout.this.getHandler().post(this);
        }
    }
};
/* access modifiers changed from: private */
public boolean dpadCenterPressed = false;
/* access modifiers changed from: private */
public long lastCursorUpdate = System.currentTimeMillis();
private Paint paint = new Paint();
PointF tmpPointF = new PointF();

public interface Callback {
    void onUserInteraction();
}

/* access modifiers changed from: private */
public float bound(float f, float f2) {
    if (f > f2) {
        return f2;
    }
    float f3 = -f2;
    return f < f3 ? f3 : f;
}

public CursorLayout(Context context) {
    super(context);
    init();
}

public CursorLayout(Context context, AttributeSet attributeSet) {
    super(context, attributeSet);
    init();
}

private void init() {
    if (!isInEditMode()) {
        this.paint.setAntiAlias(true);
        setWillNotDraw(false);
        Display defaultDisplay = ((WindowManager) getContext().getSystemService(getContext().WINDOW_SERVICE)).getDefaultDisplay();
        Point point = new Point();
        defaultDisplay.getSize(point);
        this.EFFECT_RADIUS = point.x / 20;
        this.EFFECT_DIAMETER = this.EFFECT_RADIUS * 2;
        CURSOR_STROKE_WIDTH = (float) (point.x / 400);
        CURSOR_RADIUS = point.x / 110;
        MAX_CURSOR_SPEED = (float) (point.x / 25);
        SCROLL_START_PADDING = point.x / 15;
    }
}

public void setCallback(Callback callback2) {
    this.callback = callback2;
}

public boolean onInterceptTouchEvent(MotionEvent motionEvent) {
    Callback callback2 = this.callback;
    if (callback2 != null) {
        callback2.onUserInteraction();
    }
    return super.onInterceptTouchEvent(motionEvent);
}

/* access modifiers changed from: protected */
public void onSizeChanged(int i, int i2, int i3, int i4) {
    super.onSizeChanged(i, i2, i3, i4);
    UtilMethods.LogMethod("cursorView123_", "onSizeChanged");
    if (!isInEditMode()) {
        this.cursorPosition.set(((float) i) / 2.0f, ((float) i2) / 2.0f);
        if (getHandler() != null) {
            getHandler().postDelayed(this.cursorHideRunnable, 5000);
        }
    }
}

public boolean dispatchKeyEvent(KeyEvent keyEvent) {
    UtilMethods.LogMethod("cursorView123_", "dispatchKeyEvent");
    Callback callback2 = this.callback;
    if (callback2 != null) {
        callback2.onUserInteraction();
    }
    int keyCode = keyEvent.getKeyCode();
    if (!(keyCode == 66 || keyCode == 160)) {
        switch (keyCode) {
            case 19:
                if (keyEvent.getAction() == 0) {
                    if (this.cursorPosition.y <= 0.0f) {
                        return super.dispatchKeyEvent(keyEvent);
                    }
                    handleDirectionKeyEvent(keyEvent, -100, -1, true);
                } else if (keyEvent.getAction() == 1) {
                    handleDirectionKeyEvent(keyEvent, -100, 0, false);
                }
                return true;
            case 20:
                if (keyEvent.getAction() == 0) {
                    if (this.cursorPosition.y >= ((float) getHeight())) {
                        return super.dispatchKeyEvent(keyEvent);
                    }
                    handleDirectionKeyEvent(keyEvent, -100, 1, true);
                } else if (keyEvent.getAction() == 1) {
                    handleDirectionKeyEvent(keyEvent, -100, 0, false);
                }
                return true;
            case 21:
                if (keyEvent.getAction() == 0) {
                    if (this.cursorPosition.x <= 0.0f) {
                        return super.dispatchKeyEvent(keyEvent);
                    }
                    handleDirectionKeyEvent(keyEvent, -1, -100, true);
                } else if (keyEvent.getAction() == 1) {
                    handleDirectionKeyEvent(keyEvent, 0, -100, false);
                }
                return true;
            case 22:
                if (keyEvent.getAction() == 0) {
                    if (this.cursorPosition.x >= ((float) getWidth())) {
                        return super.dispatchKeyEvent(keyEvent);
                    }
                    handleDirectionKeyEvent(keyEvent, 1, -100, true);
                } else if (keyEvent.getAction() == 1) {
                    handleDirectionKeyEvent(keyEvent, 0, -100, false);
                }
                return true;
            case 23:
                break;
            default:
                switch (keyCode) {
                    case 268:
                        if (keyEvent.getAction() == 0) {
                            handleDirectionKeyEvent(keyEvent, -1, -1, true);
                        } else if (keyEvent.getAction() == 1) {
                            handleDirectionKeyEvent(keyEvent, 0, 0, false);
                        }
                        return true;
                    case 269:
                        if (keyEvent.getAction() == 0) {
                            handleDirectionKeyEvent(keyEvent, -1, 1, true);
                        } else if (keyEvent.getAction() == 1) {
                            handleDirectionKeyEvent(keyEvent, 0, 0, false);
                        }
                        return true;
                    case 270:
                        if (keyEvent.getAction() == 0) {
                            handleDirectionKeyEvent(keyEvent, 1, -1, true);
                        } else if (keyEvent.getAction() == 1) {
                            handleDirectionKeyEvent(keyEvent, 0, 0, false);
                        }
                        return true;
                    case 271:
                        if (keyEvent.getAction() == 0) {
                            handleDirectionKeyEvent(keyEvent, 1, 1, true);
                        } else if (keyEvent.getAction() == 1) {
                            handleDirectionKeyEvent(keyEvent, 0, 0, false);
                        }
                        return true;
                }
        }
    }
    if (!isCursorDissappear()) {
        if (keyEvent.getAction() == 0 && !getKeyDispatcherState().isTracking(keyEvent)) {
            getKeyDispatcherState().startTracking(keyEvent, this);
            this.dpadCenterPressed = true;
            dispatchMotionEvent(this.cursorPosition.x, this.cursorPosition.y, 0);
        } else if (keyEvent.getAction() == 1) {
            getKeyDispatcherState().handleUpEvent(keyEvent);
            dispatchMotionEvent(this.cursorPosition.x, this.cursorPosition.y, 1);
            this.dpadCenterPressed = false;
        }
        return true;
    }
    return super.dispatchKeyEvent(keyEvent);
}

/* access modifiers changed from: private */
public void dispatchMotionEvent(float f, float f2, int i) {
    UtilMethods.LogMethod("cursorView123_", "dispatchMotionEvent");
    long uptimeMillis = SystemClock.uptimeMillis();
    long uptimeMillis2 = SystemClock.uptimeMillis();
    PointerProperties pointerProperties = new PointerProperties();
    pointerProperties.id = 0;
    pointerProperties.toolType = 1;
    PointerProperties[] pointerPropertiesArr = {pointerProperties};
    PointerCoords pointerCoords = new PointerCoords();
    pointerCoords.x = f;
    pointerCoords.y = f2;
    pointerCoords.pressure = 1.0f;
    pointerCoords.size = 1.0f;
    dispatchTouchEvent(MotionEvent.obtain(uptimeMillis, uptimeMillis2, i, 1, pointerPropertiesArr, new PointerCoords[]{pointerCoords}, 0, 0, 1.0f, 1.0f, 0, 0, 0, 0));
}

private void handleDirectionKeyEvent(KeyEvent keyEvent, int i, int i2, boolean z) {
    this.lastCursorUpdate = System.currentTimeMillis();
    if (!z) {
        getKeyDispatcherState().handleUpEvent(keyEvent);
        this.cursorSpeed.set(0.0f, 0.0f);
    } else if (!getKeyDispatcherState().isTracking(keyEvent)) {
        Handler handler = getHandler();
        handler.removeCallbacks(this.cursorUpdateRunnable);
        handler.post(this.cursorUpdateRunnable);
        getKeyDispatcherState().startTracking(keyEvent, this);
    } else {
        return;
    }
    Point point = this.cursorDirection;
    if (i == -100) {
        i = point.x;
    }
    if (i2 == -100) {
        i2 = this.cursorDirection.y;
    }
    point.set(i, i2);
}

/* access modifiers changed from: protected */
public void dispatchDraw(Canvas canvas) {
    super.dispatchDraw(canvas);
    UtilMethods.LogMethod("cursorView123_", "dispatchDraw");
    if (!isInEditMode() && !isCursorDissappear()) {
        float f = this.cursorPosition.x;
        float f2 = this.cursorPosition.y;
        this.paint.setColor(Color.argb(128, 255, 255, 255));
        this.paint.setStyle(Style.FILL);
        canvas.drawCircle(f, f2, (float) CURSOR_RADIUS, this.paint);
        this.paint.setColor(-7829368);
        this.paint.setStrokeWidth(CURSOR_STROKE_WIDTH);
        this.paint.setStyle(Style.STROKE);
        canvas.drawCircle(f, f2, (float) CURSOR_RADIUS, this.paint);
    }
}

private boolean isCursorDissappear() {
    return System.currentTimeMillis() - this.lastCursorUpdate > 5000;
}

/* access modifiers changed from: protected */
public void onDraw(Canvas canvas) {
    super.onDraw(canvas);
}}

then put the webview inside custom cursor layout in XML

<com.example.webviewtvapp.CursorLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/cursorLayout">

    <WebView
        android:id="@+id/webView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

</com.example.webviewtvapp.CursorLayout>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM