Android开发:如何获取RelativeLayout中Delete按钮ImageView的位置坐标?
解决Android中获取删除按钮坐标不准确的问题
你遇到的getLocationInWindow()返回x=0的问题,几乎都是因为在View还没完成布局绘制的时机调用了该方法(比如直接在onCreate()里调用),这时候View还没被系统测量和摆放,自然拿不到正确的位置。下面是几种靠谱的解决方式:
方法1:使用View.post()延迟获取坐标
post()会把你的任务放到View的消息队列中,等View完成布局、绘制后再执行,这时候就能拿到准确的坐标和宽高:
ImageView deleteButton = findViewById(R.id.deleteButton); deleteButton.post(new Runnable() { @Override public void run() { int[] location = new int[2]; // 获取按钮在窗口中的坐标 deleteButton.getLocationInWindow(location); int btnX = location[0]; int btnY = location[1]; // 获取按钮的宽高,用来计算完整的可交互区域 int btnWidth = deleteButton.getWidth(); int btnHeight = deleteButton.getHeight(); // 构建按钮的矩形区域(用于判断拖放是否进入该区域) Rect deleteArea = new Rect(btnX, btnY, btnX + btnWidth, btnY + btnHeight); // 之后你就可以用这个deleteArea来判断拖放的ListView项是否进入删除区域了 } });
方法2:使用ViewTreeObserver监听布局完成
如果需要在更早的时机获取坐标,可以用ViewTreeObserver监听全局布局完成事件:
ImageView deleteButton = findViewById(R.id.deleteButton); ViewTreeObserver observer = deleteButton.getViewTreeObserver(); observer.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { @Override public void onGlobalLayout() { // 记得移除监听,避免重复触发 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { deleteButton.getViewTreeObserver().removeOnGlobalLayoutListener(this); } else { deleteButton.getViewTreeObserver().removeGlobalOnLayoutListener(this); } int[] location = new int[2]; deleteButton.getLocationInWindow(location); int btnX = location[0]; int btnY = location[1]; int btnWidth = deleteButton.getWidth(); int btnHeight = deleteButton.getHeight(); Rect deleteArea = new Rect(btnX, btnY, btnX + btnWidth, btnY + btnHeight); // 使用deleteArea进行拖放判断 } });
额外提示:判断拖放区域的逻辑
在你的拖放回调(比如自定义的OnDragListener或者拖放手势监听)中,你可以通过以下方式判断拖放的View是否进入删除区域:
// 假设dragView是正在被拖放的ListView项 int[] dragLocation = new int[2]; dragView.getLocationInWindow(dragLocation); Rect dragArea = new Rect(dragLocation[0], dragLocation[1], dragLocation[0] + dragView.getWidth(), dragLocation[1] + dragView.getHeight()); // 判断两个矩形是否重叠(即拖放项进入了删除区域) if (Rect.intersects(deleteArea, dragArea)) { // 执行删除操作 }
内容的提问来源于stack exchange,提问作者Manoj Kumar
相关产品推荐
相关产品推荐

