闲聊

View,对我们来说在熟悉不过了,从接触 Android 开始,我们就一直在接触 View,界面当中到处都是 View,比如我们经常用到的 TextViewButtonLinearLayout 等等,但是我们真的了解 View 吗?尤其是 View 的坐标。

mLeftmRightmYmXmTranslationYmScoollY 相对于屏幕的坐标等等这些概念你真的清楚了吗?如果真的清楚了,那你没有必要读这篇博客,如果你还是有一些模糊,建议花上几分钟的时间读一下。

为什么要写这一篇博客呢?因为掌握 View 的坐标很重要,尤其是对于 自定义View,学习动画有重大的意义。这篇博客主要讲解一下问题:

  • View 的 getLeft() 和 getRight() 和 getTop() 和 getBottom()

  • View 的 getY(), getTranslationY() 和 getTop() 之间的联系

  • View 的 getScroollY 和 View 的 scrollTo() 和 scrollBy()

  • event.getY() 和 event.getRawY()

  • 扩展,怎样获取状态栏(StatusBar)和标题栏(titleBar)的高度

View中相应API

event.getX()表示的是触摸的点距离自身左边界的距离 
event.getY()表示的是触摸的点距离自身上边界的距离
event.getRawX()表示的是触摸点距离屏幕左边界的距离
event.getRawY()表示的是触摸点距离屏幕上边界的距离 
 
view.getTop()表示的是自身view顶部以父View的左上角为原点的垂直坐标位置 ;
view.getBottom()表示的是自身view底部以父View的左上角为原点的垂直坐标位置 ;
view.getLeft()表示的是自身view左侧以其父View的左上角为原点的水平坐标位置 ;
view.getRight()表示的自身view右侧以其父View的左上角为原点的水平坐标位置 ;
 
 
view.getWidth()表示自身view宽度;
view.getHeight()表示自身view高度 ;
 
view.getTranslationX()计算的是该View在X轴的偏移量。初始值为0,向左偏移值为负,向右偏移值为正。 
view.getTranslationY()计算的是该View在Y轴的偏移量。初始值为0,向上偏移为负,向下偏移为证。 

基本概念

简单说明一下(上图 Activity 采用 默认Style,状态栏和标题栏都会显示):最大的草绿色区域是屏幕界面,红色次大区域我们称之为“应用界面区域”,最小紫色的区域我们称之为“View绘制区域”;屏幕顶端、应用界面区之外的那部分显示手机电池网络运营商信息的为“状态栏”,应用区域顶端、View 绘制区外部显示 Activity 名称的部分我们称为“标题栏”。

从这张图片我们可以看到,在 Android 中,当 ActionBar 存在的情况下:

屏幕的 高度 = 状态栏+应用区域的高度 = 状态栏的 高度 +(标题栏的 高度 + View 绘制区域的高度)

当 ActionBar 不存在的情况下:

屏幕的高度= 状态栏+应用区域的高度 = 状态栏的 高度+(View 绘制区域的 高度)

View 的 getLeft() 和 getRight() 和 getTop() 和 getBottom()

top 是左上角纵坐标,left 是左上角横坐标,right 是右下角横坐标,bottom 是右下角纵坐标,都是相对于它的直接 父View 而言的,而不是相对于屏幕而言的。这一点要区分清楚。那哪个坐标是相对于屏幕而言的呢,以及要怎样获取相对于屏幕的坐标呢?

目前 View 里面的变量还没有一个是相对于屏幕而言的,但是我们可以获取到相对于屏幕的坐标。一般来说,我们要获取 View 的坐标和高度 等,都必须等到 View 绘制完毕以后才能获取的到,在 Activity 的 onCreate() 方法 里面 是获取不到的,必须等到 View 绘制完毕以后才能获取地到 View 的响应的坐标,一般来说,主要有以下两种方法。

第一种方法onWindowFocusChanged() 方法里面进行调用:

第二种方法,在视图树绘制完成的时候进行测量:

View 的 getY(), getTranslationY() 和 getTop() 之间的联系

  • getY()

Added in API level 14

The visual y position of this view, in pixels.(返回的是View视觉上的图标,即我们眼睛看到位置的Y坐标,默认值跟getTop()相同,别急,下面会解释)

  • getTranslationY()

Added in API level 14

The vertical position of this view relative to its top position, in pixels.(竖直方向上相对于top的偏移量,默认值为0)

那 getY() 和 getTranslationY() 和 getTop() 到底有什么关系呢?

从以上的源码我们可以知道 getY() = getTranslationY()+ getTop(),而 getTranslationY() 的默认值是0,除非我们通过 setTranlationY() 来改变它,这也就是我们上面上到的 getY()  默认值跟 getTop() 相同

那我们要怎样改变 top值 和 Y值 呢? 很明显就是调用相应的 set 方法 ,即 setY() 和setTop(),就可以改变他们的值。

View 的 getScroollY() 和 View 的 scrollTo() 和 scrollBy()

getScrollY() 是一个比较特别的函数,因为它涉及一个值叫 mScrollY,简单说,getScrollY() 一般得到的都是0,除非你调用过 scrollTo 或 scrollBy 这两个函数来改变它。

  • scrollTo() 和 scrollBy()

从字面意思我们可以知道 scrollTo() 是滑动到哪里的意思 ,scrollBy() 是相对当前的位置滑动了多少。当然这一点在源码中也是可以体现出来的:

有几点需要注意的是:

1. 不论是 scrollTo 或 scrollBy,其实都是对 View 的内容进行滚动而不是对View本身,你可以做个小实验,一个 LinearLayout 背景是黄色,里面放置一个 子LinearLayout 背景是蓝色,调用 scrollTo 或 scrollBy,移动的永远是蓝色的 子LinearLayout

2. 还有就是 scrollTo 和 scrollBy 函数的参数和坐标系是“相反的”,比如 scrollTo(-100,0),View 的内容是向 X轴正方向 移动的,这个相反打引号是因为并不是真正的相反,具体可以看源码,关于这两个函数的源码分析大家可以看:

Android——源码角度分析View的scrollBy()和scrollTo()的参数正负问题

http://blog.csdn.net/xplee0576/article/details/24242383

View 的 width 和 height

我们可以看到 Android 的 height 是由 mBottom 和 mTop 共同得出的,那我们要怎样设置 Android的 高度呢?

有人会说直接在 xml 里面设置 android:height=”” 不就OK了,那我们如果要动态设置 height 的高度呢,怎么办?你可能会想到 setWidth() 方法?但是我们找遍了 View 的所有方法,都没有发现 setWidth() 方法,那要怎样动态设置 height 呢?其实有两种方法:

第二种方法,单独地改变 top 或者 bottom 的值,这种方法不推荐使用。

至于 width,它跟 height 基本一样,只不过它是有 mRight 和 mLeft 共同决定而已。

需要注意的是,平时我们在执行动画的过程,不推荐使用 LayoutParams 来改变 View 的状态,因为改变LayoutParams 会调用 requestLayout() 方法,会标记 当前View 及 父容器,同时逐层向上提交,直到ViewRootImpl 处理该事件,ViewRootImpl 会调用三大流程,从 measure 开始,对于每一个含有标记位的 view 及其 子View 都会进行测量、布局、绘制,性能较差,源码体现如下:关于 requestLayout() 方法的更多分析可以查看这一篇博客:

Android View 深度分析requestLayout、invalidate与postInvalidate

http://blog.csdn.net/a553181867/article/details/51583060

因此我们如果在 api 14 以后 ,在动画执行过程中,要改变 View 的状态,推荐使用 setTranslationY() 和setTranslationX() 等方法,而尽量避免改变 LayoutParams.因为性能来说较差。

event.getY() 和 event.getRawY()

要区分于 MotionEvent.getRawX() 和 MotionEvent.getX()

 public boolean onTouch(View view, MotionEvent event) 中,当你触到控件时,x,y 是相对于该控件 左上点(控件本身)的相对位置。 而 rawxrawy 始终是相对于屏幕的位置。getX() 是表示 Widget 相对于自身左上角的 x坐标,而 getRawX() 是表示相对于屏幕左上角的x坐标值 (注意: 这个屏幕左上角是手机屏幕左上角,不管 Activity 是否有 TitleBar 或是否全屏幕)。

扩展,怎样获取状态栏(StatusBar)和标题栏(titleBar)的高度

这里我们需要注意的 是在 ActionBar 存在的情况下,通过这种方法我们才能够得出 titleBar 的高度,否则是无法得到的,因为 viewTop 为 0.

你真的了解View的坐标吗?的更多相关文章

  1. 在Android中将子View的坐标转换为父View的坐标

    在Android中,我们有时候可能会将子View的坐标转换为父View中的坐标.感觉很有用,分享给大家. 在Launcher中有这么一段代码可以完成这项工作.  public float getDes ...

  2. 一个view相对于屏幕或者另外一个view 的坐标

    如果想知道一个view相对于屏幕或者另外一个view 的坐标,那么可以通过如下的方法得到: UIWindow * window=[[[UIApplication sharedApplication] ...

  3. Unity 坐标 转换 详解 World世界坐标 Screen屏幕坐标 View视口坐标 GUI坐标 NGUI坐标 localPosition相对父级坐标

    在制作游戏中我们经常会遇到这样一个需求: 在人物模型的上面显示 名字.称号 一类的文字或者图片 如下图 人物模型属于是Camera1   UI Title信息属于NGUI Camera2 如下图 这时 ...

  4. 28 自定义View画坐标和柱状图

    自定义View类 RectView.java package com.qf.sxy.day29_customview.widget; import android.content.Context; i ...

  5. 当前View的坐标相对其他View的位置坐标

    // 将rect由rect所在视图转换到目标视图view中,返回在目标视图view中的rect - (CGRect)convertRect:(CGRect)rect toView:(UIView *) ...

  6. Android View相关知识问答

    Android View相关核心知识问答 Activity Window View之间的三角关系 你真的了解View的坐标吗? 在渲染前获取 View 的宽高 5种手势工具类 浅析Android的窗口

  7. view坐标_ _ Android应用坐标系统全面详解

    转:http://blog.csdn.net/yanbober/article/details/50419117 1 背景 去年有很多人私信告诉我让说说自定义控件,其实通观网络上的很多博客都在讲各种自 ...

  8. Android必知必会-获取View坐标和长宽的时机

    如果移动端访问不佳,请访问–>Github版 背景 最近要实现一个功能,用到了一些属性动画,需要获取一些View的坐标信息,设计图如下: 这里我使用的是DialogFragment来实现的,可以 ...

  9. 在Android中动画移动一个View的位置,采用Scroller类实现Android动画之 View移动

    在Android中动画移动一个View的位置,采用Scroller类实现 今天说最近自己遇到的一个问题,就是要用动画效果来移动一个VIew的位置. 这个具体的情况是,需要做一个SlidingMenu的 ...

随机推荐

  1. (转) rabbitmq应用场景

    原文:http://blog.csdn.net/wangpengblog/article/details/76405598

  2. 手风琴图片和钢琴导航栏JQ滑动特效

    手风琴JQ滑动特效 1.效果预览: 2.相关代码: <!DOCTYPE html> <html lang="en"> <head> <me ...

  3. JDK1.10+scala环境的搭建之linux环境(centos6.9)

    ---恢复内容开始--- 第一步:安装jdk1.10版本 进入网页 http://oracle.com/technetwork/java/javase/downloads/index.html  下载 ...

  4. vmware 实现linux目录映射window本地目录

    ---恢复内容开始--- 背景: 1,使用lnmp环境 2,代码可以在windows上面写,直接映射到linux的lnmp环境下面 第一步: vmware 新建一个linux虚拟机 一路下一步到完成 ...

  5. Android 开发服务类 01_ServletForXML

    Servlet implementation class NewsListServlet package com.wangjialin.server.xml; import java.io.IOExc ...

  6. C/C++ -- Gui编程 -- Qt库的使用 -- Qt编码问题

    1.直接使用QObject::trUtf8("中文字符串") 2.头文件<QTextCodec>QTextCodec::setCodecForTr(QTextCodec ...

  7. PHP 运行相关概念

    web server.cgi.cgi程序.fast-cgi.php-fpm.php-cgi

  8. vscode 常用配置

    { "workbench.iconTheme": "vscode-icons", "editor.tabSize": 2, "ed ...

  9. Nginx+Memcached+Tomcat集群配置

    1.   Nginx Nginx是通过将多个Web Server绑定到同一个IP地址下,以实现多个WebServer间的负载均衡,降低单个Web Server的负荷,以提高整体的性能与稳定性. 安装和 ...

  10. Linux 64位 CentOS下安装 Docker 容器,启动、停止

    一.Docker简介 Docker 提供了一个可以运行你的应用程序的封套(envelope),或者说容器,是轻量级的“容器引擎+映像仓库”,在LXC(linux轻量级容器)的基础上构建,可以运行任何应 ...