使用场景:
令悬浮窗始终在屏幕之内
原理
在 setOnTouchListener
中, 监听悬浮窗坐标,
如果超出屏幕, 就把悬浮窗坐标设置为屏幕边缘
代码讲解
- 悬浮窗布局
var window = floaty.rawWindow( <frame gravity="center" bg="#ff00ff"> <button id="action" w="300dp" h="300dp"> 按钮 </button> </frame> );
- 保持悬浮窗不被关闭
ui.post(function () { windowWidth = window.getWidth(); windowHeight = window.getHeight(); }, 1000);
- 触摸监听
window.action.setOnTouchListener
- 触摸监听有三种情况:
ACTION_DOWN
ACTION_MOVE
ACTION_UP
我们主要处理 ACTION_MOVE
ACTION_MOVE
- 坐标系有两个轴: x, y
- 悬浮窗在x轴上有以下情形
- 悬浮窗x < 0
- 0 < 悬浮窗x < 设备宽度
- 悬浮窗x > 设备宽度
- 悬浮窗在y轴上与x轴情况类似
- 所以我们一共有 3 * 3 = 9 种情况
超出屏幕的悬浮窗
几个坐标的意义
关键理解: 预测未来
- 我们判断悬浮窗超出屏幕之外, 是去计算当前的悬浮窗, 如果移动了某段距离,
那么, 未来这个悬浮窗的某个部分, 就可能超出屏幕之外, 我们就看不见一个完整的悬浮窗了 - 我们要计算的是, (当前悬浮窗坐标 + 未来移动的距离) 是否 超出屏幕边缘
- 如果未来悬浮窗的坐标超出屏幕边缘, 我们就将悬浮窗置于屏幕边缘
关键代码
let xAxisMovingDistance = event.getRawX() - x; let yAxisMovingDistance = event.getRawY() - y; if (windowX + xAxisMovingDistance < 0) { if (windowY + yAxisMovingDistance < 0) { window.setPosition(0, 0); } else if (windowY + windowHeight + yAxisMovingDistance > device.height) { window.setPosition(0, device.height - windowHeight); } else { window.setPosition(0, windowY + yAxisMovingDistance); } } else if (windowX + xAxisMovingDistance > device.width - windowWidth) { if (windowY + yAxisMovingDistance < 0) { window.setPosition(device.width - windowWidth, 0); } else if (windowY + windowHeight + yAxisMovingDistance > device.height) { window.setPosition(device.width - windowWidth, device.height - windowHeight); } else { window.setPosition(device.width - windowWidth, windowY + yAxisMovingDistance); } } else { if (windowY + yAxisMovingDistance < 0) { window.setPosition(windowX + xAxisMovingDistance, 0); } else if (windowY + windowHeight + yAxisMovingDistance > device.height) { window.setPosition(windowX + xAxisMovingDistance, device.height - windowHeight); } else { window.setPosition(windowX + xAxisMovingDistance, windowY + yAxisMovingDistance); } }