Android中坐标体系知识超详细讲解

news2024/12/18 14:22:42

说来说去都不如画图示意简单易懂啊!!!真是的! 来吧先上张图!

(一)首先明确一下android 中的坐标系统:
屏幕的左上角是坐标系统原点(0,0)
原点向右延伸是X轴正方向,原点向下延伸是Y轴正方向


(二)关于Scroll: 屏幕显示的内容很多时,会有超出一屏的情况,于是就产生了Scroll的概念。
在View类中有个方法:

getScrollY() 英文原文描述是:
Return the scrolled top position of this view. This is the top edge of the displayed part of your
view....

其实理解起来仍然就是:就是这个view相对于“坐标系统原点”(见上图)在Y轴上的偏移量.
(getScrollX同理)
【哇哈,有了图就是好说明啊~ 省了多少语言描述啊,而且还不一定能说清楚~】
getScrollY()就是当前视图相对于屏幕原点在Y轴上的偏移量.


(三)MotionEvent类中getRowX()和getX()的区别:
event.getRowX():触摸点相对于屏幕原点的x坐标event.getX(): 触摸点相对于其所在组件
原点的x坐标
于是乎: view.getScrollY() + event.getY() 就得到了view中的触摸点在Y轴上的偏移量


(四)TextView类中
有个getLayout()方法:the Layout that is currently being used to display the text. This
can be null if the text or width has recently changes.
其返回类型是Layout ,也就是返回textView的布局。
然后重要的是通过这个layout调用一个方法:
getLineForVertical(int verticalPointPosition) //得到某点在垂直方向上的行数值
于是综上所述,在实际的触摸事件中可以这样使用:
Layout layout=textView.getLayout();
int line = layout.getLineForVertical(textView.getScrollY() + (int) event.getY());

//得到触摸点在textView中垂直方向上的行数值。参数是触摸点在Y轴上的偏移量
接下来继续介绍一个方法, 要用到上边的layout 和line:
layout.getOffsetForHorizontal( line , (int) event.getX() );
//得到触摸点在某一行水平方向上的偏移量。
参数分别是: 该行行数值和触摸点在该行X轴上的偏移量。
此方法得到的该值会根据该行上的文字的多少而变化,并不是横向上的像素大小;

整个坐标系是以手机屏幕左上角为原点(0,0),如果在屏幕没有滑动之前,这一理解肯定是ok
的,但在滑屏之后,就会产生很多歧义和混淆,原因在于使用过程当中,很多方法的参数并非是
参照屏幕,而是相对于父视图,对这整个过程和后面自定义控件的坐标变化带来的各个参数变化
来说理解起来就并不那么适合了,最开始给人的感觉是越来越不清楚这个坐标该怎么设置,好像
坐标系总在发生变化,后来才慢慢在思维当中构建起视图与视图容器以及屏幕之间的关系。


android.view.View.layout(int l, int t, int r, int b) layout的过程就是确定View在屏幕上显示的具体位
置,在代码中就是设置其成员变量mLeft,mTop,mRight,mBottom的值,这几个值构成的矩形
区域就是该View显示的位置, 不过这里的具体位置都是相对与父视图的位置。mLeft代表当前
view.layout的这个view的左边缘离它的父视图左边缘的距离,拿上面“子视图2.layout(int l, int t,
int r, int b) ”来说,它的父视图便是子视图1,2,3合起来形成的整个大矩形,那么这里将父视图的左
上角定为(0,0),那么可以确定mLeft为一个子视图宽度320,以此类推, mTop指当前view的上边
缘离父视图上边缘的距离。而以此为界, mRight所指的是当前view的右边缘离父视图左边缘的

距离,一眼可以看出值为640(mLeft+自己的宽度),mBottom也是指当前view的下边缘离父视
图的上边缘的距离。至于为何如此,大概是因为坐标系的缘故,坐标中的任何点都必须以(0,0)为
起点,XY轴为衡量。


视图左侧位置view.getLeft() 视图右侧位置view.getRight()
视图顶部位置view.getTop(); 视图底部位置view.getBottom(); 这四个方法所获取到的各个左上右
下的值与layout的四个参数代表的是一样的,都是相对父视图的左边缘与上边缘。
视图宽度view.getWidth(); 视图高度view.getHeight() ; 这两个方法获取的是该view的高和宽,仅
仅在滑动的情况下,或者说该view的大小如果不发生变化,它的值是不会变的。
getMeasuredWidth(); getMeasuredHeight(); 说到这里就不得不提getWidth()、getHeight()和
getMeasuredWidth()、getMeasuredHeight()这两对函数之间的区别,getMeasuredWidth()、
getMeasuredHeight()返回的是measure过程得到的mMeasuredWidth和mMeasuredHeight的值,
而getWidth()和getHeight()返回的是mRight - mLeft和mBottom - mTop的值。

一般情况下layout过程会参考measure过程中计算得到的mMeasuredWidth和mMeasuredHeight来安排子视图在父视图中显示的位置,但这不是必须的,measure过程得到的结果可能完全没有实际用处,特别是对于一些自定义的ViewGroup,其子视图的个数、位置和大小都是固定的,这时候我们可以忽略整个measure过程,只在layout函数中传入的4个参数来安排每个子视图的具体位置。
view.getX(); view.getY(); getX和getY获取到的值为相对于父视图而言的两个左边缘和上边缘的距
离。


view.getLocationOnScreen(location); 该方法可以获取到当前view与屏幕的关系,location(0)代表
X值,表示该view的左边缘与屏幕的左边缘之间的距离。可以想象,当滑屏产生,view开始移动该
值肯定会改变的。location(1)代表Y值,表示该view的上边缘与屏幕的上边缘之间的距离,该距离
肯定是包含标题栏的高度的。getLocationInWindow();
ps:View.getLocationInWindow()和View.getLocationOnScreen()在window占据全部screen时,
返回值相同,不同的典型情况是在Dialog中时。当Dialog出现在屏幕中间时,
View.getLocationOnScreen()取得的值要比View.getLocationInWindow()取得的值要大。
VelocityTracker.getXVelocity() 指滑动速度包括速率和方向两个方面,往左滑动小于0,值为负;
往右滑动大于0,值为正。


view.scrollTo (x,y) 将整个父视图的左上角定为(0,0),再移动这个屏幕的左上角到父视图的点(x,y)
处,注意此处的x和y是根据父视图的坐标系来定的。view.scrollBy(x,y) x代表横向移动的距离,y
代表纵向移动的距离
view.getScrollX view.getScrollY 将整个父视图的左上角定为(0,0),那么子view. getScrollX会获取
到屏幕左边缘减去父视图的左边缘为0的距离,特别当滑屏时,父视图会被迫隐藏一部分,因为屏
幕的大小是固定的。getScrollY以此类推。

event.getX() event.getY() 该方法是不受视图影响的,X和Y的值仅仅代表手指在以左上角(0,0)为原
点的屏幕触摸点的坐标值。
Scroller.getCurrY() Scroller.getCurrX() 该方法拿横轴来说,代表屏幕的左边缘离父视图的左边缘的
距离。


Scroller.startScroll( int startX, int startY, int dx, int dy) 四个参数分别表示起点的坐标和滑动的向
量,即从( startX, startY)开始滑动,横向滑动dx的距离,纵向滑动dy的距离(正值向左滑,负值向
右滑),而这里的startX, startY又是参照的父视图左上角为原点坐标的坐标系,滑屏时经常使用
getScrollX()和getScrollY()来代表屏幕左边缘和上边缘处于父视图坐标系的具体位置
TranslateAnimation() 参数参照:http://blog.sina.com.cn/s/blog_90b91bf10101ai3e.html
以上是在做滑屏控件经常用到的方法,一方面需要了解layout和measure的基本流程,更重要一方
面,当你想要实现某一个效果的时候,比如slidingmenu那样的控件,查看源码我们可以知道它是
继承的ViewGroup,该怎样入手去做呢。


首先,需要了解它的父视图是什么,slidingmenu为例,打开程序,第一眼,是一个很普通的视图
页面,当向右滑动手指,这个视图页面开始向右边移动,而从左边会慢慢移出来另一部分视图,
看上去像是抽出来的或者是隐藏的,事实上抛开阴影效果来讲,想象手机屏幕的左边有一部分我
们看不到的视图,它就是这个被抽出来的menu视图了。

概括来说,一个主view,一个menu其实
是并排于一个大视图上面的。找到了父视图,接下来就好办了,认定这个父视图的宽度就是主
view的宽度和menu的宽度之和(暂不考虑padding之类),高度就是屏幕的高度,那么在思维当中
这个二维平面就产生了,将它想成一张纸,然后对准主view将这张纸贴到手机屏幕上,左右滑
动,会看到其实slidingmenu也就是这么个效果。


然后,实现的思路会清晰很多。定义这个父视图为myview继承viewgroup,原因在于尽管主view
和menu并排在一个大view下,但毕竟两者的内容不同,后面需要放进不同的控件处理不同的事
件,这个父视图内包含着两个view,到时候处理起来会方便很多,setcontentview为这个父视
图,那么打开程序的第一眼就会看到它。再定义这两个view设置好两个内容布局,并将它们
addview添加到myview当中。外部工作基本就完成了,可以呈现父视图,并且父视图内有两个子
view。
接下来,需要去完善一些细节,父视图内的子view该如何放置,这是关乎成败的一环,也就是如
何将这张纸贴到我们希望的位置,这时就是onlayout的处理了,处理好屏幕,父视图子view之间
的位置关系,通过各自的layout参数设置来摆放妥当各个view,比如开始的时候menu是隐藏的,
这个就是通过位置的摆放设置的,然后它是从左边滑出来的,说明它处于父视图的左边位置,而
主view处于相对右边的位置,而屏幕刚好也处于父视图右边的位置,恰好能看到主view的全貌,
在脑海里如果能有清晰的画面出现,实现起来就会轻松很多。当实现了这个摆放,就可以理解
menudrawer里面上下左右都可以滑出menu的结构了。


最后,便是滑动效果,请相信这样的控件里面,任何处理肯定都会和view位置的摆放扯上关系,
滑动方向,滑动距离等等都涉及到坐标的处理。这也是为何上面列出那些常用的获取view坐标的方法。


总结下来,构建类似这样的控件,也就这三点,明确父子视图和屏幕的关系,通过坐标和位置参
数设置它们的关系,处理这些关系发生变化的情况。
当然,事实上slidingmenu远远没这么简单,其中为了方便后续开发,它内置了很多接口和处理,
大多数都是位置坐标和事件监听相关联,而万变不离其宗的是,它也肯定有这三个方面的构建,
理解了这些基本的东西,尝试做一些自己想象的效果,对自定义的理解来说,进步会非常大。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2261635.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

IO的进阶

目录 1. 字符流转向字节流的桥梁1.1 OutputStreamWriter1.2 InputStreamReader1.3 编码与解码1.4 常见编码方式1.5 编码与解码的注意事项 2.Properties2.1概述2.2 Properties 的常用方法2.3 Properties 的应用场景2.4 实例 3.序列化3.1 ObjectOutputStream 4.字符编码4.1 ASCII…

【计算机网络】期末考试预习复习|中

作业讲解 转发器、网桥、路由器和网关(4-6) 作为中间设备,转发器、网桥、路由器和网关有何区别? (1) 物理层使用的中间设备叫做转发器(repeater)。 (2) 数据链路层使用的中间设备叫做网桥或桥接器(bridge)。 (3) 网络层使用的中间设备叫做路…

Edge Scdn用起来怎么样?

Edge Scdn:提升网站安全与性能的最佳选择 在当今互联网高速发展的时代,各种网络攻击层出不穷,特别是针对网站的DDoS攻击威胁,几乎每个行业都可能成为目标。为了确保网站的安全性与稳定性,越来越多的企业开始关注Edge …

UE4_控件蓝图_制作3D生命血条

一:效果图如下: 二、实现步骤: 1、新建敌人 右键蓝图类 选择角色, 重命名为BP_Enemytest。 双击打开,配置敌人网格体 修改位置及朝向 效果如下: 选择合适的动画蓝图类: 人物就有了动作&#x…

厦门凯酷全科技有限公司引领电商营销新风尚

在当今数字化经济快速发展的背景下,抖音作为领先的短视频和直播平台,已成为品牌推广和产品销售的重要渠道。厦门凯酷全科技有限公司(以下简称“凯酷全”)凭借其专业的团队和丰富的经验,专注于为客户提供高质量的抖音电…

高扬程潜水泵:大流量与高效率的完美结合|深圳鼎跃

洪水是由暴雨、风暴潮等等自然因素引起的江河湖海水量迅速增加或水位迅猛上涨的水流现象。一旦发生洪水事件,会侵袭河道沿岸的城市、农田等场景,在低洼地区容易形成积水,不仅影响人们的生活,还存在一定的安全风险。 高扬程潜水泵是…

神经网络基础-神经网络搭建和参数计算

文章目录 1.构建神经网络2. 神经网络的优缺点 1.构建神经网络 在 pytorch 中定义深度神经网络其实就是层堆叠的过程,继承自nn.Module,实现两个方法: __init__方法中定义网络中的层结构,主要是全连接层,并进行初始化。…

web网页前后端交互方式

参考该文&#xff0c; 一、前端通过表单<form>向后端发送数据 前端是通过html中的<form>表单&#xff0c;设置method属性定义发送表单数据的方式是get还是post。 如使用get方式&#xff0c;则提交的数据会在url中显示&#xff1b;如使用post方式&#xff0c;提交…

Mac配置 Node镜像源的时候报错解决办法

在Mac电脑中配置国内镜像源的时候报错,提示权限问题,无法写入配置文件。本文提供解决方法,青测有效。 一、原因分析 遇到的错误是由于 .npm 目录下的文件被 root 用户所拥有,导致当前用户无法写入相关配置文件。 二、解决办法 在终端输入以下命令,输入管理员密码即可。 su…

Linux实操篇-远程登录/Vim/开机重启

目录 传送门前言一、远程登录1、概念2、ifconfig3、实战3.1、SSH&#xff08;Secure Shell&#xff09;3.2、VNC&#xff08;Virtual Network Computing&#xff09;3.3、RDP&#xff08;Remote Desktop Protocol&#xff09;3.4、Telnet&#xff08;不推荐&#xff09;3.5、FT…

【C/C++进阶】CMake学习笔记

本篇文章包含的内容 一、CMake简介二、使用CMake构建工程2.1 一个最简单的CMake脚本2.2 使用变量和宏2.3 文件搜索 三、使用CMake制作和使用库文件3.1 静态库和动态库3.2 字符串操作3.3 CMake制作库文件3.4 CMake使用库文件3.4.1 使用link_libraries链接3.4.2 使用target_link_…

JS 生成防篡改水印

网页中有水印的需求&#xff0c;今天我们实现手写一个防篡改水印&#xff0c;先看下效果图&#xff1a; 一、创建class函数 传递一个dom为水印包裹器&#xff0c;有一些监听防篡改的observer&#xff0c;然后实例化的时候创建水印&#xff0c;执行create()方法 class WaterMa…

概率论得学习和整理26:EXCEL 关于plot 折线图--频度折线图的一些细节

目录 0 折线图有很多 1 频度折线图 1.1 直接用原始数据做的频度折线图 2 将原始数据生成数据透视表 3 这样可以做出了&#xff0c;频度plot 4 做按某字段汇总&#xff0c;成为累计plot分布 5 修改上面显示效果&#xff0c;做成百分比累计plot频度分布 0 折线图有很多 这…

实现echart大屏动画效果及全屏布局错乱解决方式

如何实现echarts动画效果?如何实现表格或多个垂直布局的柱状图自动滚动效果?如何解决tooltip位置超出屏幕问题,如何解决legend文字过长,布局错乱问题?如何处理饼图的中心图片永远居中? 本文将主要解决以上问题,如有错漏,请指正. 一、大屏动画效果 这里的动画效果主要指&…

pytest入门九:feature

fixture是pytest特有的功能&#xff0c;用以在测试执行前和执行后进行必要的准备和清理工作。使用pytest.fixture标识&#xff0c;定义在函数前面。在你编写测试函数的时候&#xff0c;你可以将此函数名称做为传入参数&#xff0c;pytest将会以依赖注入方式&#xff0c;将该函数…

C# 中的闭包

文章目录 前言一、闭包的基本概念二、匿名函数中的闭包1、定义和使用匿名函数2、匿名函数捕获外部变量3、闭包的生命周期 三、Lambda 表达式中的闭包1、定义和使用 Lambda 表达式2、Lambda 表达式捕获外部变量3、闭包的作用域 四、闭包的应用场景1、事件处理2、异步编程3、迭代…

ChatGPT客户端安装教程(附下载链接)

用惯了各类AI的我们发现每天打开网页还挺不习惯和麻烦&#xff0c;突然发现客户端上架了&#xff0c;懂摸鱼的人都知道这里面的道行有多深&#xff0c;话不多说&#xff0c;开整&#xff01; 以下是ChatGPT客户端的详细安装教程&#xff0c;适用于Windows和Mac系统&#xff1a…

GRE over IPSec 如何应用?如何在ensp上配置GRE over IPSec 实验?

GRE over IPSec应用场景 IPSec VPN本端设备无法感知对端有几个设备 &#xff0c;本端共用一个IPSec SA 。报文封装中没有对端设备的下一跳 &#xff0c;所以无法传输组播、广播和非IP报文 &#xff0c;比如OSPF协议 &#xff0c;导致分支与总部的内部网络之间无法使用OSPF路由…

概率论得学习和整理29: 用EXCEL 描述二项分布

目录 1 关于二项分布的基本内容 2 二项分布的概率 2.1 核心要素 2.2 成功K次的概率&#xff0c;二项分布公式 2.3 期望和方差 2.4 具体试验 2.5 概率质量函数pmf 和cdf 3 二项分布的pmf图的改进 3.1 改进折线图 3.2 如何生成这种竖线图呢 4 不同的二项分布 4.1 p0.…

leetcode 面试经典 150 题:三数之和

链接三数之和题序号11类型数组解题方法排序双指针法难度中等 题目 给你一个整数数组 nums &#xff0c;判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i ! j、i ! k 且 j ! k &#xff0c; 同时还满足 nums[i] nums[j] nums[k] 0 。请你返回所有和为 0 且不重复的三…