Подтвердить что ты не робот

Получение координат по отношению к корневому расположению

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

4b9b3361

Ответ 1

Это одно из решений, хотя с тех пор, как 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, если хотите.

Ответ 2

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

Ответ 3

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

Просто используйте 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();

Ответ 4

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;

Вот doc

Ответ 5

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().

Ответ 6

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

view.getLocationOnScreen(int [] location)

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

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

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

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

 int[] img_coordinates = new int[2];

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

  // 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];

Ответ 7

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

В нем говорится: Можно получить местоположение представления, вызвав методы 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

Ответ 8

Если кто-то все еще пытается понять это. Так вы получите центр 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;

Ответ 9

Я написал себе два метода полезности, которые, похоже, работают в большинстве условий, обрабатывая прокрутку, перевод и масштабирование, но не вращение. Я сделал это, пытаясь использовать 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;
}