如何获得视图的绝对坐标

我试图获取视图左上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]; 

笔记

  • getLocationOnScreenreplacegetLocationInWindow应该在大多数情况下给出相同的结果(参见这个答案 )。
  • 如果您在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 valuey valuePoint对象

 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);