代码之家  ›  专栏  ›  技术社区  ›  fhucho

获取视图相对于根布局的坐标

  •  126
  • fhucho  · 技术社区  · 14 年前

    我能得到一个视图的X和Y位置相对于我在Android中活动的根布局吗?

    9 回复  |  直到 6 年前
        1
  •  131
  •   ramblinjan    11 年前

    这是一个解决方案,尽管随着时间的推移,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
  •  104
  •   carlo.marinangeli    6 年前

    Android API已经提供了实现这一点的方法。 试试这个:

    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

        3
  •  90
  •   Jonik    10 年前

    请使用 view.getLocationOnScreen(int[] location); (见 Javadocs )答案在整数数组(x)中= location[0] y= location[1] )

        4
  •  33
  •   Clint Deygoo    8 年前

    不需要手动计算。

    只使用 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();
    
        5
  •  31
  •   Kerrmiter    10 年前
    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
  •  6
  •   Hitesh Sahu    8 年前

    你可以用

    在屏幕上查看.getlocation(int[]位置)

    ;`以正确获取视图的位置。

    但是有一个 抓住 如果在布局充气之前使用它,您将得到错误的位置。

    这个问题的解决方案是添加 ViewTreeObserver 像这样:

    全局声明数组以存储视图的x y位置

     int[] img_coordinates = new int[2];
    

    然后添加 视图树服务器 在父布局上获取布局膨胀的回调,然后获取视图位置 否则你会得到错误的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
  •  2
  •   Alexander Hugestrand    8 年前

    我给自己写了两种在大多数情况下都有效的实用方法,处理滚动、翻译和缩放,但不处理旋转。在框架中尝试使用offsetDescendantRectomyCoords()之后,我这样做了,因为它的准确性不一致。它在某些情况下起作用,但在其他情况下却产生了错误的结果。

    “点”是一个包含两个元素(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;
    }
    
        8
  •  1
  •   donmj    9 年前

    我刚找到答案 here

    它说: 可以通过调用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
    
        9
  •  1
  •   Sheraz Ahmad Khilji    7 年前

    如果有人还在想办法解决这个问题。这就是如何得到 view .

        int pos[] = new int[2];
        view.getLocationOnScreen(pos);
        int centerX = pos[0] + view.getMeasuredWidth() / 2;
        int centerY = pos[1] + view.getMeasuredHeight() / 2;