getLocalVisibleRect()、getGlobalVisibleRect()、getLocationOnScreen()、getLocationInWinow方法浅析

getLocalVisibleRect()、getGlobalVisibleRect()、getLocationOnScreen()、getLocationInWinow()、getWindowVisibleDisplayFrame()

如上几个方法有什么区别与联系,本文整理一下。

感谢参考链接1、 参考链接2参考链接3作者提供的分享。本文在此参考链接基础上总结整理。

一、前提条件

1.view.visibility = View.VISIBLE,即控件正常可见,至于INVISIBLE、View.GONE情况未测试,但是推测INVISIBLE应该与VISIBLE表现相同,有兴趣继续探讨的同学可留言交流。

2.getLocalVisibleRect()、getGlobalVisibleRect()返回值都是true,至于返回false情况,未做测试。根据sdk文档来看,如果控件被父布局部分完全遮盖或者完全滚动到屏幕外,方法会返回false。

3.屏幕分辨率设置1px = 1dp,大小为320w x 480h。

二、分析

如下布局:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
                xmlns:tools="http://schemas.android.com/tools"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:id="@+id/container"
                tools:context=".MainActivity">
    <LinearLayout
        android:layout_width="320dp"
        android:layout_height="480dp"
        android:orientation="vertical"
        android:id="@+id/innerL"
        android:background="#550000ff"
        android:layout_marginLeft="-50px"
        android:layout_marginTop="30px">
    </LinearLayout>
</RelativeLayout>

1.getLocalVisibleRect() 是 获取视图本身可见的坐标区域,坐标以自己的左上角为原点(0,0)。

 得到localRect(50, 0 - 320, 369),其实就是对应着坐标(left,top,right,bottom)。

50代表该控件的left,是从控件左起第50像素开始显示在屏幕最左边的。左边由于layout_marginLeft="-50px",导致控件有一部分显示在屏幕外边。

0代表该控件的top,是从控件上起第0像素开始显示在屏幕上的。距离屏幕上边的距离是 statusbar高度20 + actionbar高度60 +marginTop高度30 = 110 像素开始显示控件top的。

320代表该控件的right,是从控件左起第50~320像素显示在屏幕上的。本例中320未超出屏幕右侧,所以控件右侧边完全显示出来了。

370 代表控件的bottom,是从控件上起到显示出控件最下边距离为370,剩余的480 - 370 = 110被显示到屏幕外边了。屏幕总高度480 - statusbar高度20 - actionbar高度60 - marginTop高度30 = 屏幕剩余可显示区域的高度370。

2.getGlobalVisibleRect() 是 获取视图在屏幕坐标中的可视区域(从屏幕最左上角(0,0)开始,相当于statusbar的左上角)。

得到坐标globalRect(0, 110 - 270, 480),其实就是对应着坐标(left,top,right,bottom)。

0代表从屏幕左起第x = 0像素开始显示该控件。从控件的第50像素开始显示到屏幕的x = 0坐标上,控件左边由于layout_marginLeft="-50px",导致控件有一部分显示在屏幕外边。

110代表从屏幕上起第y =110像素开始显示该控件的top。

270代表从屏幕左起第0~270像素的范围显示该控件。本例中控件右侧未超出屏幕右侧,所以控件右侧完全显示出来了。

480 代表从屏幕上起第y =110 ~ y = 480像素范围显示该控件。控件的下半部分还有 屏幕总高度480 - 屏幕剩余可显示高度 = 屏幕总高度480 - (屏幕总高度480 - statusbar高度20 - actionbar高度60 - marginTop高度30) = 110像素 显示到屏幕外边了。

3.getLocationOnScreen(location)

一个控件在其整个屏幕上的坐标位置

location[0] 屏幕的x坐标,location[1] 屏幕的y坐标 ,控件的左上角在屏幕的(x,y)坐标开始显示

4.getLocationInWindow(location)

一个控件在其父窗口中的坐标位置

location[0] 父控件的x坐标,location[1] 父控件的y坐标 ,控件的左上角在父控件的(x,y)坐标开始显示

5.getWindowVisibleDisplayFrame()

获取屏幕可视窗口区域大小,并非某个View的可视区域大小,所以用窗口中的任意View来执行都是没有差别的。一般来说可以使用当前窗口的根View来执行这个方法,也就是调用Window对象的getDecorView().getWindowVisibleDisplayFrame()来获取。只有View对象已经attach到Window上之后,调用此方法才能得到真实的窗口的可视区域大小。当View是INVISIBLE的时候,其onDraw()方法不会被调用,当View是GONE的时候,其onDraw()和onLayout()方法不会被调用。但无论是INVISIBLE或者GONE,onAttachedToWindow()都会被调用,也就是说View会被attach到Window上,所以即使View是INVISIBLE或者GONE的,getWindowVisibleDisplayFrame()也能够正确的返回。

三、注意:

1.对于getLocalVisibleRect()、getGlobalVisibleRect()而言,一定要注意当他们返回值是true的时候,也就是至少有一部分显示在屏幕上的时候,这个规则才有效。如果控件在scrollview中滚出屏幕外或者GONE,不显示在屏幕上了,返回false的情况还需进一步探索。

2.对于getLocationOnScreen()、getLocationInWindow()而言,不论是不是由于scrollview滚动到屏幕外边了,都会取到逻辑上的相对坐标值。比如屏幕总高度是480,但是目标控件由于在scrollview下面还没显示在屏幕上,那么可能取到的值是500,是逻辑上的坐标。

 

 

 

 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值