Получение координат представления относительно корневого макета

Могу ли я получить позицию x и y в представлении относительно корневого макета моей активности в Android?

Это одно из решений, хотя с тех пор, как API меняются со временем, и могут быть другие способы сделать это, обязательно проверьте другие ответы. Один утверждает, что он быстрее, а другой утверждает, что он легче.

private int getRelativeLeft(View myView) { if (myView.getParent() == myView.getRootView()) return myView.getLeft(); else return myView.getLeft() + getRelativeLeft((View) myView.getParent()); } private int getRelativeTop(View myView) { if (myView.getParent() == myView.getRootView()) return myView.getTop(); else return myView.getTop() + getRelativeTop((View) myView.getParent()); } 

Дай мне знать, если это работает.

Он должен рекурсивно просто добавлять верхнюю и левую позиции из каждого родительского контейнера. Вы также можете реализовать его с помощью Point если хотите.

Используйте view.getLocationOnScreen(int[] location); (см. Javadocs ). Ответ находится в массиве integer (x = location[0] и y = location[1] ).

API Android уже предоставляет метод для достижения этого. Попробуй это:

 Rect offsetViewBounds = new Rect(); //returns the visible bounds childView.getDrawingRect(offsetViewBounds); // calculates the relative coordinates to the parent parentViewGroup.offsetDescendantRectToMyCoords(childView, offsetViewBounds); int relativeTop = offsetViewBounds.top; int relativeLeft = offsetViewBounds.left; 

Вот документ

Не нужно вычислять его вручную.

Просто используйте getGlobalVisibleRect так:

 Rect myViewRect = new Rect(); myView.getGlobalVisibleRect(myViewRect); float x = myViewRect.left; float y = myViewRect.top; 

Также обратите внимание, что для центральных координат, а не что-то вроде:

 ... float two = (float) 2 float cx = myViewRect.left + myView.getWidth() / two; float cy = myViewRect.top + myView.getHeight() / two; 

Вы можете просто сделать:

 float cx = myViewRect.exactCenterX(); float cy = myViewRect.exactCenterY(); 
 View rootLayout = view.getRootView().findViewById(android.R.id.content); int[] viewLocation = new int[2]; view.getLocationInWindow(viewLocation); int[] rootLocation = new int[2]; rootLayout.getLocationInWindow(rootLocation); int relativeLeft = viewLocation[0] - rootLocation[0]; int relativeTop = viewLocation[1] - rootLocation[1]; 

Сначала я получаю корневой макет, а затем вычисляю разницу координат с видом.
Вы также можете использовать getLocationOnScreen() вместо getLocationInWindow() .

Вы можете использовать `

view.getLocationOnScreen (int [] location)

; `чтобы правильно определить местоположение вашего представления.

Но есть уловка, если вы используете его до того, как макет был завышен, вы получите неправильную позицию.

Решение этой проблемы заключается в добавлении ViewTreeObserver следующим образом:

Объявить глобально массив для хранения xy позиции вашего представления

  int[] img_coordinates = new int[2]; 

а затем добавьте ViewTreeObserver на свой родительский макет, чтобы получить обратный вызов для инфляции макета и только затем получить позицию представления, иначе вы получите неправильные координаты xy

  // set a global layout listener which will be called when the layout pass is completed and the view is drawn parentViewGroup.getViewTreeObserver().addOnGlobalLayoutListener( new ViewTreeObserver.OnGlobalLayoutListener() { public void onGlobalLayout() { //Remove the listener before proceeding if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { parentViewGroup.getViewTreeObserver().removeOnGlobalLayoutListener(this); } else { parentViewGroup.getViewTreeObserver().removeGlobalOnLayoutListener(this); } // measure your views here fab.getLocationOnScreen(img_coordinates); } } ); 

а затем использовать его так

 xposition = img_coordinates[0]; yposition = img_coordinates[1]; 

Я написал себе два метода полезности, которые, похоже, работают в большинстве условий, обрабатывая прокрутку, перевод и масштабирование, но не rotation. Я сделал это, пытаясь использовать offsetDescendantRectToMyCoords () в структуре, которая имела непоследовательную точность. Он работал в некоторых случаях, но дал другие результаты.

«point» – это массив с плавающей точкой с двумя элементами (координаты x и y), «предк» – это группа представлений где-то выше «потомок» в иерархии дерева.

Сначала метод, который идет от координат потомков к предку:

 public static void transformToAncestor(float[] point, final View ancestor, final View descendant) { final float scrollX = descendant.getScrollX(); final float scrollY = descendant.getScrollY(); final float left = descendant.getLeft(); final float top = descendant.getTop(); final float px = descendant.getPivotX(); final float py = descendant.getPivotY(); final float tx = descendant.getTranslationX(); final float ty = descendant.getTranslationY(); final float sx = descendant.getScaleX(); final float sy = descendant.getScaleY(); point[0] = left + px + (point[0] - px) * sx + tx - scrollX; point[1] = top + py + (point[1] - py) * sy + ty - scrollY; ViewParent parent = descendant.getParent(); if (descendant != ancestor && parent != ancestor && parent instanceof View) { transformToAncestor(point, ancestor, (View) parent); } } 

Затем обратный, от предка до потомка:

 public static void transformToDescendant(float[] point, final View ancestor, final View descendant) { ViewParent parent = descendant.getParent(); if (descendant != ancestor && parent != ancestor && parent instanceof View) { transformToDescendant(point, ancestor, (View) parent); } final float scrollX = descendant.getScrollX(); final float scrollY = descendant.getScrollY(); final float left = descendant.getLeft(); final float top = descendant.getTop(); final float px = descendant.getPivotX(); final float py = descendant.getPivotY(); final float tx = descendant.getTranslationX(); final float ty = descendant.getTranslationY(); final float sx = descendant.getScaleX(); final float sy = descendant.getScaleY(); point[0] = px + (point[0] + scrollX - left - tx - px) / sx; point[1] = py + (point[1] + scrollY - top - ty - py) / sy; } 

Я только что нашел ответ здесь

В нем говорится: можно получить местоположение представления, вызвав методы getLeft () и getTop (). Первая возвращает левую или X координату прямоугольника, представляющего представление. Последний возвращает верхнюю или Y координату прямоугольника, представляющего представление. Эти методы возвращают местоположение представления относительно его родителя. Например, когда getLeft () возвращает 20, это означает, что представление расположено на 20 пикселей справа от левого края его прямого родителя.

поэтому используйте:

 view.getLeft(); // to get the location of X from left to right view.getRight()+; // to get the location of Y from right to left 

Если кто-то все еще пытается понять это. Вот как вы получаете центр X и Y view .

  int pos[] = new int[2]; view.getLocationOnScreen(pos); int centerX = pos[0] + view.getMeasuredWidth() / 2; int centerY = pos[1] + view.getMeasuredHeight() / 2; 
Давайте будем гением компьютера.