如何获得视图的绝对坐标
我试图获取视图左上angular的绝对屏幕像素坐标。 但是,我可以find的所有方法,如getLeft()
和getRight()
都不起作用,因为它们看起来都是相对于视图的父对象的,所以给我0
。 什么是正确的方法来做到这一点?
如果有帮助,这是为了“把照片放回原处”。 我希望用户能够绘制一个框来select多个部分。 我的假设是,最简单的方法是从getRawX()
和getRawY()
,然后将这些值与布局的左上angular进行比较。 知道了件的大小,我可以确定有多less件被选中。 我意识到我可以在getX()
上使用getX()
和getY()
,但是因为这会返回一个相对位置,使得确定哪些部分被选中更困难。 (不是不可能,我知道,但似乎不必要的复杂)。
编辑:这是我用来获取容器的大小的代码,按照其中一个问题。 TableLayout
是包含所有拼图的表格。
TableLayout tableLayout = (TableLayout) findViewById(R.id.tableLayout); Log.d(LOG_TAG, "Values " + tableLayout.getTop() + tableLayout.getLeft());
编辑2:这是我试过的代码,更多的build议的答案。
public int[] tableLayoutCorners = new int[2]; (...) TableLayout tableLayout = (TableLayout) findViewById(R.id.tableLayout); tableLayout.requestLayout(); Rect corners = new Rect(); tableLayout.getLocalVisibleRect(corners); Log.d(LOG_TAG, "Top left " + corners.top + ", " + corners.left + ", " + corners.right + ", " + corners.bottom); cells[4].getLocationOnScreen(tableLayoutCorners); Log.d(LOG_TAG, "Values " + tableLayoutCorners[0] + ", " + tableLayoutCorners[1]);
所有初始化完成后添加此代码。 图像被分成一个包含在TableLayout
的ImageViews(cells []数组)。 单元格[0]是左上方的ImageView
,我select了单元格[4],因为它在中间的某个地方,绝对不应该有(0,0)的坐标。
上面显示的代码仍然给我所有的日志中的0,我真的不明白,因为各种拼图正确显示。 (我尝试了public int int tableLayoutCorners和默认可见性,都给出了相同的结果。)
我不知道这是否意义重大,但ImageView
最初没有给出一个大小。 当我给它一个图像来显示时, ImageView
的大小在View自动初始化过程中被确定。 这可能有助于他们的值为0,即使该日志代码是在他们已经被赋予了一个图像,并自动resize? 为了对付这个问题,我添加了如上所示的代码tableLayout.requestLayout()
,但是这并没有帮助。
使用View.getLocationOnScreen()
和/或getLocationInWindow()
。
首先你必须得到视图的localVisible矩形
例如:
Rect rectf = new Rect(); //For coordinates location relative to the parent anyView.getLocalVisibleRect(rectf); //For coordinates location relative to the screen/display anyView.getGlobalVisibleRect(rectf); Log.d("WIDTH :", String.valueOf(rectf.width())); Log.d("HEIGHT :", String.valueOf(rectf.height())); Log.d("left :", String.valueOf(rectf.left)); Log.d("right :", String.valueOf(rectf.right)); Log.d("top :", String.valueOf(rectf.top)); Log.d("bottom :", String.valueOf(rectf.bottom));
希望这会有所帮助
接受的答案实际上并没有说明如何获得位置,所以这里是更详细一点。 您传递一个长度为2的int
数组,并将值replace为视图的(x,y)坐标(顶部,左上angular)。
int[] location = new int[2]; myView.getLocationOnScreen(location); int x = location[0]; int y = location[1];
笔记
- 用
getLocationOnScreen
replacegetLocationInWindow
应该在大多数情况下给出相同的结果(参见这个答案 )。 - 如果您在
onCreate
调用此方法,您将得到(0,0)
,因为视图尚未布置。 您可以使用ViewTreeObserver
来监听布局何时完成,您可以获取测量的坐标。 (看到这个答案 )
使用全局布局侦听器对我来说一直效果不错。 它具有能够在布局改变时重新测量事物的优点,例如,如果设置了View.GONE或者子视图被添加/移除。
public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // inflate your main layout here (use RelativeLayout or whatever your root ViewGroup type is LinearLayout mainLayout = (LinearLayout ) this.getLayoutInflater().inflate(R.layout.main, null); // set a global layout listener which will be called when the layout pass is completed and the view is drawn mainLayout.getViewTreeObserver().addOnGlobalLayoutListener( new ViewTreeObserver.OnGlobalLayoutListener() { public void onGlobalLayout() { //Remove the listener before proceeding if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { mainLayout.getViewTreeObserver().removeOnGlobalLayoutListener(this); } else { mainLayout.getViewTreeObserver().removeGlobalOnLayoutListener(this); } // measure your views here } } ); setContentView(mainLayout); }
遵循罗曼·盖伊的评论,这里是我如何解决它。 希望它能帮助也有这个问题的其他人。
我确实想要把这些意见的立场摆在屏幕上,但是一点也不明显。 那些代码在启动代码运行之后被放置,所以我认为一切都准备好了。 但是,这个代码仍然在onCreate(); 通过对Thread.sleep()的实验,我发现在onCreate()一直到onResume()完成执行之前,布局并没有实际完成。 所以确实,代码试图在布局完成之前运行在屏幕上。 通过将代码添加到一个OnClickListener(或其他一些监听器)获得正确的值,因为它只能在布局完成后触发。
下面的行被build议为社区编辑:
请使用onWindowfocuschanged(boolean hasFocus)
使用此代码查找确切的X和Y坐标:
int[] array = new int[2]; ViewForWhichLocationIsToBeFound.getLocationOnScreen(array); if (AppConstants.DEBUG) Log.d(AppConstants.TAG, "array X = " + array[0] + ", Y = " + array[1]); ViewWhichToBeMovedOnFoundLocation.setTranslationX(array[0] + 21); ViewWhichToBeMovedOnFoundLocation.setTranslationY(array[1] - 165);
我已经添加/减去了一些值来调整我的观点。 只有在整个观点已经膨胀之后,请做这些线。
我的utils函数获取视图位置,它将返回一个具有x value
和y value
的Point
对象
public static Point getLocationOnScreen(View view){ int[] location = new int[2]; view.getLocationOnScreen(location); return new Point(location[0], location[1]); }
运用
Point viewALocation = getLocationOnScreen(viewA);