android中getLocationInWindow 和 getLocationOnScreen的区别

原文链接:http://blog.csdn.net/ouyang_peng/article/details/46902957

//一个控件在其父窗口中的坐标位置
View.getLocationInWindow(int[] location);

//一个控件在其整个屏幕上的坐标位置
View.getLocationOnScreen(int[] location);

getLocationOnScreen

getLocationInWindow是以B为原点的C的坐标
getLocationOnScreen以A为原点。

下面是getLocationOnScreen示例

start = (Button) findViewById(R.id.start);  
        int []location=new int[2];  
        start.getLocationOnScreen(location);  
        int x=location[0];//获取当前位置的横坐标  
        int y=location[1];//获取当前位置的纵坐标  

下面是getLocationInWindow示例

start = (Button) findViewById(R.id.start);  
        int []location=new int[2];  
        start.getLocationInWindow(location);  
        int x=location[0];//获取当前位置的横坐标  
        int y=location[1];//获取当前位置的纵坐标  

getLocationInWindow

/**
     * <p>Computes the coordinates of this view in its window. The argument
     * must be an array of two integers. After the method returns, the array
     * contains the x and y location in that order.</p>
     *
     * @param outLocation an array of two integers in which to hold the coordinates
     */
    public void getLocationInWindow(@Size(2) int[] outLocation) {
        if (outLocation == null || outLocation.length < 2) {
            throw new IllegalArgumentException("outLocation must be an array of two integers");
        }

        outLocation[0] = 0;
        outLocation[1] = 0;

        transformFromViewToWindowSpace(outLocation);
    }

    /** @hide */
    public void transformFromViewToWindowSpace(@Size(2) int[] inOutLocation) {
        if (inOutLocation == null || inOutLocation.length < 2) {
            throw new IllegalArgumentException("inOutLocation must be an array of two integers");
        }

        if (mAttachInfo == null) {
            // When the view is not attached to a window, this method does not make sense
            inOutLocation[0] = inOutLocation[1] = 0;
            return;
        }

        float position[] = mAttachInfo.mTmpTransformLocation;
        position[0] = inOutLocation[0];
        position[1] = inOutLocation[1];

        if (!hasIdentityMatrix()) {
            getMatrix().mapPoints(position);
        }

        position[0] += mLeft;
        position[1] += mTop;

        ViewParent viewParent = mParent;
        while (viewParent instanceof View) {
            final View view = (View) viewParent;

            position[0] -= view.mScrollX;
            position[1] -= view.mScrollY;

            if (!view.hasIdentityMatrix()) {
                view.getMatrix().mapPoints(position);
            }

            position[0] += view.mLeft;
            position[1] += view.mTop;

            viewParent = view.mParent;
         }

        if (viewParent instanceof ViewRootImpl) {
            // *cough*
            final ViewRootImpl vr = (ViewRootImpl) viewParent;
            position[1] -= vr.mCurScrollY;
        }

        inOutLocation[0] = Math.round(position[0]);
        inOutLocation[1] = Math.round(position[1]);
    }

getLocationOnScreen

/**
     * <p>Computes the coordinates of this view on the screen. The argument
     * must be an array of two integers. After the method returns, the array
     * contains the x and y location in that order.</p>
     *
     * @param outLocation an array of two integers in which to hold the coordinates
     */
    public void getLocationOnScreen(@Size(2) int[] outLocation) {
        getLocationInWindow(outLocation);

        final AttachInfo info = mAttachInfo;
        if (info != null) {
            outLocation[0] += info.mWindowLeft;
            outLocation[1] += info.mWindowTop;
        }
    }

Android中获取坐标点的一些方法解释

一、getLocationInWindow和getLocationOnScreen的区别

// location [0]—>x坐标,location [1]—>y坐标
int[] location = new int[2] ;

// 获取在当前窗口内的绝对坐标,getLeft , getTop, getBottom, getRight, 这一组是获取相对在它父窗口里的坐标。
view.getLocationInWindow(location);

// 获取在整个屏幕内的绝对坐标,注意这个值是要从屏幕顶端算起,也就是包括了通知栏的高度。
view.getLocationOnScreen(location);

如果在Activity的OnCreate()事件输出那些参数,是全为0,要等UI控件都加载完了才能获取到这些。
在onWindowFocusChanged(boolean hasFocus)中获取为好。

View.getLocationInWindow()和 View.getLocationOnScreen()在window占据全部screen时,返回值相同,不同的典型情况是在Dialog中时。当Dialog出现在屏幕中间时,View.getLocationOnScreen()取得的值要比View.getLocationInWindow()取得的值要大。

二、Android View坐标getLeft, getRight, getTop, getBottom

理解坐标,位置概念

这里涉及坐标系的概念:

坐标系在二维视图中通过X轴和Y轴两个数字为组合表示某个点的绝对坐标。 例如(30, 100) 通常表示X轴30, Y轴100交叉的一个点

在Android中可以把left相当于X轴值, top相当于Y轴值, 通过这两个值Android系统可以知道视图的绘制起点,在通过Wdith 和 Height 可以得到视图上下左右具体值,就可以在屏幕上绝对位置绘制视图。right 与 bottom计算如下:

right = left + width;

bottom = top + height;

相应API

视图左侧位置 view.getLeft()

视图右侧位置 view.getRight()

视图顶部位置 view.getTop();

视图底部位置 view.getBottom();

视图宽度 view.getWidth();

视图高度 view.getHeight()

实例分析

按照我的理解:

蓝色区域位置 left = 0, top = 0 坐标(0, 0 )

黄色区域位置 left = 60, top = 115 坐标(60, 115)

绿色区域位置 left = 115, top = 170 坐标(115, 170)

委屈 绿色区域,这里理解错误,我认为绿色区域的位置是针对于蓝色区域的(0, 0)坐标的值,从上图的右下角打印出的坐标值就可以看出与下方我列出的值不一致,看看下面的图就明白了

getLocationOnScreen

总结: 视图的left , top , right , bottom 的值是针对其父视图的相对位置, 绿色区域是针对其父视图(即黄色区域为(0, 0)点)的坐标,不应该是(115, 170 ) 而是 (55, 55)

getLocationOnScreen

public class MainActivity extends AppCompatActivity {
    private RelativeLayout rl1;
    private RelativeLayout rl2;
    private TextView       tv;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }

    @Override
    public void onWindowFocusChanged(boolean hasFocus) {
        super.onWindowFocusChanged(hasFocus);
        rl1 = (RelativeLayout) findViewById(R.id.rl1);
        rl2 = (RelativeLayout) findViewById(R.id.rl2);
        tv = (TextView) findViewById(R.id.tv);

        int[] rl1_location = new int[2];
        int[] rl2_location = new int[2];
        int[] tv_location = new int[2];

        rl1.getLocationInWindow(rl1_location);
        rl2.getLocationInWindow(rl2_location);
        tv.getLocationInWindow(tv_location);

        System.out.println(rl1_location[0] + ":" + rl1_location[1]);
        System.out.println(rl2_location[0] + ":" + rl2_location[1]);
        System.out.println(tv_location[0] + ":" + tv_location[1]);
        System.out.println("rl2 left:" + rl2.getLeft() + " top: " + rl2.getTop());

        rl1.getLocationOnScreen(rl1_location);
        rl2.getLocationOnScreen(rl2_location);
        tv.getLocationOnScreen(tv_location);

        System.out.println(rl1_location[0] + ":" + rl1_location[1]);
        System.out.println(rl2_location[0] + ":" + rl2_location[1]);
        System.out.println(tv_location[0] + ":" + tv_location[1]);
    }
}
12-09 09:25:20.345 8345-8345/com.google.testdemo I/System.out: 0:243
12-09 09:25:20.345 8345-8345/com.google.testdemo I/System.out: 126:631
12-09 09:25:20.345 8345-8345/com.google.testdemo I/System.out: 426:931
12-09 09:25:20.345 8345-8345/com.google.testdemo I/System.out: rl2 left:126 top: 388
12-09 09:25:20.345 8345-8345/com.google.testdemo I/System.out: 0:243
12-09 09:25:20.345 8345-8345/com.google.testdemo I/System.out: 126:631
12-09 09:25:20.345 8345-8345/com.google.testdemo I/System.out: 426:931
  • 4
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值