我使用Webview,它加载随机网站。为了良好的导航,我需要打开鼠标光标,这将是由D-pad控制,但我没有找到如何做到这一点的信息,也许有人可以开发这样的导航,我将感谢任何帮助。
dtcbnfnu1#
要通过创建自定义指针布局在Android TV Webview中启用光标指针
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); }}
然后将webview放入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>
z4bn682m2#
使用指针捕获
仅当包含您的应用中的视图的视图层次结构具有焦点时,该视图才能请求指针捕获。因此,您应在视图上有特定用户操作时请求指针捕获,例如在onClick()事件期间,或在Activity的onWindowFocusChanged()事件处理程序中。若要请求指针捕获,请对视图调用requestPointerCapture()方法。下面的代码示例演示如何在用户单击视图时请求指针捕获:
onClick()
onWindowFocusChanged()
requestPointerCapture()
2条答案
按热度按时间dtcbnfnu1#
要通过创建自定义指针布局在Android TV Webview中启用光标指针
然后将webview放入XML格式的自定义光标布局中
z4bn682m2#
使用指针捕获
仅当包含您的应用中的视图的视图层次结构具有焦点时,该视图才能请求指针捕获。因此,您应在视图上有特定用户操作时请求指针捕获,例如在
onClick()
事件期间,或在Activity的onWindowFocusChanged()
事件处理程序中。若要请求指针捕获,请对视图调用
requestPointerCapture()
方法。下面的代码示例演示如何在用户单击视图时请求指针捕获: