VerticalGridView的焦点无法出界的问题2021-07-19

博客探讨了在Android开发中,当View的整体和子控件设置点击及按键监听事件时,焦点行为的问题。内容指出,若View的根布局不设为focusable=false,VerticalGridView的边界子控件无法触发向外界的按键事件。这可能导致需要对整体View添加额外的onkeylistener,但这样做可能影响已有的子控件逻辑。文章强调了理解和正确处理焦点事件及布局焦点属性的重要性。

前提
1.给View整体设置了点击事件但未设置onkeylistener
2.给View中的子控件设置了点击事件和onkeylistener
3.其中View的根布局中,设置了状态addStatesFromChildren="true"但未指明focusable的值;子控件设置为focusable为true

在设置View的根布局为focusable="false"后,
VerticalGridView的焦点可以移动到VerticalGridView之外了。

问题点在于未设置View的根布局为focusable="false"时
VerticalGridView边界上的子控件的向外界移动的按键事件也没有被监听到
要额外给View整体设置onkeylistener的话很多逻辑会改写,对于原本依赖子控件按键事件的逻辑可能存在问题

### 解决方案 为了防止 `el-dialog` 组件在自定义拖拽过程中超出页面边界,可以采用监听鼠标移动事件并计算对话框位置的方法来动态调整其坐标。具体实现如下: #### HTML 部分 ```html <template> <el-dialog :visible.sync="dialogVisible" @mousedown.native="handleMouseDown"> <!-- 对话框内容 --> </el-dialog> </template> ``` #### JavaScript 方法部分 通过 Vue 实例中的方法绑定鼠标的按下、移动以及释放事件。 当检测到用户点击了 `.el-dialog__header` 或者其他指定区域时触发拖动逻辑,在此期间不断更新 dialog 的 top 和 left 属性值以保持在其可视区域内[^1]。 ```javascript export default { data() { return { dialogVisible: false, startX: 0, startY: 0, startLeft: 0, startTop: 0, isDragging: false, }; }, methods: { handleMouseDown(event) { const target = event.target; // 判断是否是在头部触发的事件 if (target.closest('.el-dialog__header')) { this.startX = event.clientX; this.startY = event.clientY; let rect = document.querySelector('.el-dialog').getBoundingClientRect(); this.startLeft = rect.left; this.startTop = rect.top; this.isDragging = true; window.addEventListener('mousemove', this.handleMouseMove); window.addEventListener('mouseup', this.handleMouseUp); } }, handleMouseMove(event) { if (!this.isDragging) return; let newX = this.startLeft + (event.clientX - this.startX); let newY = this.startTop + (event.clientY - this.startY); // 获取窗口尺寸 var winWidth = window.innerWidth || document.documentElement.clientWidth || document.body.offsetWidth; var winHeight = window.innerHeight || document.documentElement.clientHeight || document.body.offsetHeight; // 计算最大最小范围 var maxRight = winWidth - parseInt(getComputedStyle(document.querySelector('.el-dialog')).width); var maxBottom = winHeight - parseInt(getComputedStyle(document.querySelector('.el-dialog')).height); // 边界控制 newX = Math.max(0, Math.min(newX, maxRight)); newY = Math.max(0, Math.min(newY, maxBottom)); document.querySelector('.el-dialog').style.transform = `translate(${newX}px, ${newY}px)`; }, handleMouseUp() { this.isDragging = false; window.removeEventListener('mousemove', this.handleMouseMove); window.removeEventListener('mouseup', this.handleMouseUp); } } } ``` 上述代码实现了对 `el-dialog` 拖拽边界的限制功能,确保即使用户尝试将对话框移至屏幕边缘之外也不会发生越界现象。
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值