Android平台如何设置并读取鼠标光标位置?
Android 鼠标光标锁定中心+3D相机控制实现方案
核心逻辑
Android原生没有直接设置光标绝对位置的API,采用「隐藏系统光标+固定自定义视觉光标+捕获鼠标相对位移」的思路:
- 隐藏系统默认光标,避免用户看到光标移动
- 在屏幕中心绘制自定义光标(如十字线),给用户视觉锚点
- 捕获鼠标的相对移动量,用这个偏移量控制3D相机视角,不需要真的移动光标
测试应用实现步骤
1. 隐藏系统光标
在Activity启动时执行以下代码隐藏系统光标:
getWindow().getDecorView().setCursorVisible(false);
2. 自定义带光标锁定的View
创建自定义View处理鼠标事件并绘制中心光标:
public class CursorLockView extends View { private Paint cursorPaint; private float centerX, centerY; // 相机视角参数 private float cameraYaw = 0f; private float cameraPitch = 0f; // 鼠标灵敏度 private static final float SENSITIVITY = 0.15f; public CursorLockView(Context context) { super(context); init(); } public CursorLockView(Context context, AttributeSet attrs) { super(context, attrs); init(); } private void init() { // 初始化自定义光标画笔 cursorPaint = new Paint(); cursorPaint.setColor(Color.WHITE); cursorPaint.setStrokeWidth(3f); cursorPaint.setAntiAlias(true); // 隐藏系统光标 ((Activity) getContext()).getWindow().getDecorView().setCursorVisible(false); } @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); // 计算屏幕中心坐标 centerX = w / 2f; centerY = h / 2f; } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); // 绘制中心十字光标 canvas.drawLine(centerX - 25, centerY, centerX + 25, centerY, cursorPaint); canvas.drawLine(centerX, centerY - 25, centerX, centerY + 25, cursorPaint); // 示例:用矩形模拟3D相机视角变化(实际项目替换为你的3D渲染逻辑) canvas.save(); canvas.translate(centerX, centerY); canvas.rotate(cameraYaw); canvas.rotate(cameraPitch, 1f, 0f, 0f); canvas.drawRect(-60, -60, 60, 60, cursorPaint); canvas.restore(); } @Override public boolean onGenericMotionEvent(MotionEvent event) { // 仅处理鼠标输入 if (event.getSource() != InputDevice.SOURCE_MOUSE) { return super.onGenericMotionEvent(event); } if (event.getAction() == MotionEvent.ACTION_MOVE) { // 获取鼠标相对位移(API 23+支持) float deltaX = event.getAxisValue(MotionEvent.AXIS_RELATIVE_X); float deltaY = event.getAxisValue(MotionEvent.AXIS_RELATIVE_Y); // 更新相机视角(反转Y轴,符合鼠标控制相机的常规逻辑) cameraYaw += deltaX * SENSITIVITY; cameraPitch -= deltaY * SENSITIVITY; // 限制俯仰角度,避免过度翻转 cameraPitch = Math.max(-89f, Math.min(89f, cameraPitch)); // 刷新视图,更新相机画面和光标 invalidate(); return true; } return super.onGenericMotionEvent(event); } }
3. 在Activity中使用自定义View
public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // 直接使用自定义View作为布局 setContentView(new CursorLockView(this)); } }
兼容性处理(针对API 23以下)
如果需要兼容Android 6.0以下版本,无法直接获取相对位移,可以通过记录上一次鼠标绝对位置计算偏移:
private float lastMouseX, lastMouseY; @Override public boolean onGenericMotionEvent(MotionEvent event) { if (event.getSource() == InputDevice.SOURCE_MOUSE && event.getAction() == MotionEvent.ACTION_MOVE) { float currentX = event.getX(); float currentY = event.getY(); // 计算偏移量 float deltaX = currentX - lastMouseX; float deltaY = currentY - lastMouseY; // 更新相机视角... // 更新上一次位置 lastMouseX = currentX; lastMouseY = currentY; invalidate(); return true; } return super.onGenericMotionEvent(event); }
注意事项
- 必须保持自定义光标在屏幕中心,用户的操作始终基于这个锚点
- 灵敏度参数可以根据设备屏幕大小和用户习惯调整
- 实际项目中,将示例里的矩形绘制替换为你的3D渲染逻辑(如OpenGL、Unity视图等)
内容的提问来源于stack exchange,提问作者izzy and simple
相关产品推荐
相关产品推荐

