当前位置: 首页 > news >正文

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

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

(一)首先明确一下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远远没这么简单,其中为了方便后续开发,它内置了很多接口和处理,
大多数都是位置坐标和事件监听相关联,而万变不离其宗的是,它也肯定有这三个方面的构建,
理解了这些基本的东西,尝试做一些自己想象的效果,对自定义的理解来说,进步会非常大。

相关文章:

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

说来说去都不如画图示意简单易懂啊!!!真是的! 来吧先上张图! (一)首先明确一下android 中的坐标系统: 屏幕的左上角是坐标系统原点(0,0) 原点向右延伸是X轴正…...

不需要服务器,使用netlify快速部署自己的网站

Netlify简介 1.1 Netlify的功能与特点 Netlify 是一个功能强大的静态网站托管平台,它不仅提供了简单的网站部署功能,还集成了许多现代化的开发工具和服务,帮助开发者更高效地构建、部署和管理网站。Netlify 的核心功能包括: 自动…...

Swin transformer 论文阅读记录 代码分析

该篇文章,是我解析 Swin transformer 论文原理(结合pytorch版本代码)所记,图片来源于源paper或其他相应博客。 代码也非原始代码,而是从代码里摘出来的片段,配上简单数据,以便理解。 当然&…...

信息安全概论

文章目录 预测题重要考点1.遇到什么威胁有什么漏洞怎么缓解分析题2.网络安全现状分析 2.网络安全亮点 时间信息安全概论期末简答题软件学院实验室服务器安全风险分析与PDRR策略 1.1 信息时代的特点1.2 信息安全威胁1.3信息安全趋势1.4 研究网络与信息安全的意义2.1安全风险分析…...

2024年12月16日Github流行趋势

项目名称:PDFMathTranslate 项目维护者:Byaidu reycn hellofinch Wybxc YadominJinta项目介绍:基于 AI 完整保留排版的 PDF 文档全文双语翻译,支持 Google/DeepL/Ollama/OpenAI 等服务,提供 CLI/GUI/Docker。项目star数…...

Go 1.24即将到来!

Go 1.24 尚未发布。以下是正在撰写中的发布说明,预计 Go 1.24 将于 2025 年 2 月发布。 语言改进 Go 1.24 现在全面支持 泛型类型别名:类型别名可以像定义类型一样被参数化。详情请参阅语言规范。目前,可通过设置 GOEXPERIMENTnoaliastypep…...

FFmpeg库之ffplay

文章目录 FFmpeg环境搭建ffplay使用通用选项视频选项音频选项快捷键使用滤镜直播拉流 FFmpeg环境搭建 FFmpeg官网 FFmpeg环境搭建 ./configure \--prefix"$HOME/ffmpeg" \--extra-cflags"-I$HOME/ffmpeg/include" \--extra-ldflags"-L$HOME/ffmpeg…...

scala中模式匹配的应用

package test34object test6 {case class Person(name:String)case class Student(name:String, className:String)// match case 能根据 类名和属性的信息,匹配到对应的类// 注意:// 1 匹配的时候,case class的属性个数要对上// 2 属性名不需…...

WebRTC搭建与应用(一)-ICE服务搭建

WebRTC搭建与应用(一) 近期由于项目需要在研究前端WebGL渲染转为云渲染,借此机会对WebRTC、ICE信令协议等有了初步了解,在此记录一下,以防遗忘。 第一章 ICE服务搭建 文章目录 WebRTC搭建与应用(一)前言一、ICE是什么?二、什么…...

【计算机视觉基础CV】03-深度学习图像分类实战:鲜花数据集加载与预处理详解

本文将深入介绍鲜花分类数据集的加载与处理方式,同时详细解释代码的每一步骤并给出更丰富的实践建议和拓展思路。以实用为导向,为读者提供从数据组织、预处理、加载到可视化展示的完整过程,并为后续模型训练打下基础。 前言 在计算机视觉的深…...

Kafka学习篇

Architecture 系统间解耦,异步通信,削峰填谷 Topic 消息主题,用于存储消息 Partition 分区,通过扩大分区,可以提高存储量 Broker 部署Kafka服务的设备 Leader kafka主分区 Follwer kafka从分区 高性能之道&#xff1a…...

冬日养仓鼠小指南:温暖与陪伴同行

随着冬日的脚步悄然来临,家中可爱的小仓鼠也需要我们给予更多的关怀与呵护。仓鼠虽小,但它们的冬日养护却大有学问,关乎着这些小生命能否健康快乐地度过寒冷季节。 保暖是冬季养仓鼠的首要任务。我们可以为仓鼠的小窝增添一些保暖材料&#…...

【计算机视觉基础CV】05 - 深入解析ResNet与GoogLeNet:从基础理论到实际应用

引言 在上一篇文章中,我们详细介绍了ResNet与GoogLeNet的网络结构、设计理念及其在图像分类中的应用。本文将继续深入探讨如何在实际项目中应用这些模型,特别是如何保存训练好的模型、加载模型以及使用模型进行新图像的预测。通过这些步骤,读…...

Python爬虫之代理的设置

【1】urllib中使用公开代理 import urllib.requesturl http://www.baidu.com/s?wdipheaders {User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 Safari/537.36 }# 请求对象的定制 request urllib.req…...

Canoe E2E校验自定义Checksum算法

文章目录 一、添加 DBC文件二、导入要仿真的ECU节点三、编写 CAPL脚本1. 创建 .can 文件2. 设置counter递增3. 设置 CRC 算法,以profile01 8-bit SAE J1850 CRC校验为例 四、开始仿真五、运行结果CRC在线校验 当E2E的 CRC算法非常规算法,则需要自己编写代…...

[HNCTF 2022 Week1]你想学密码吗?

下载附件用记事本打开 把这些代码放在pytho中 # encode utf-8 # python3 # pycryptodemo 3.12.0import Crypto.PublicKey as pk from hashlib import md5 from functools import reducea sum([len(str(i)) for i in pk.__dict__]) funcs list(pk.__dict__.keys()) b reduc…...

端到端自动驾驶大模型:视觉-语言-动作模型 VLA

模型框架定义、模型快速迭代能力是考查智驾团队出活能力的两个核心指标。在展开讨论Vision-Language-Action Models(VLA)之前,咱们先来讨论端到端自动驾驶大模型设计。 目录 1. 端到端自动驾驶大模型设计 1.1 模型输入设计 1.2 模型输出设计 1.3 实现难点分析 …...

druid与pgsql结合踩坑记

最近项目里面突然出现一个怪问题,数据库是pgsql,jdbc连接池是alibaba开源的druid,idea里面直接启动没问题,打完包放在centos上和windows上cmd窗口都能直接用java -jar命令启动,但是放到国产信创系统上就是报错&#xf…...

【xxl-job】XXL-Job源码深度剖析:分布式任务调度的艺术与实践

XXL-Job源码深度剖析 核心概念1、调度中心2、执行器3、任务 来个Demo1、搭建调度中心2、执行器和任务添加3、创建执行器和任务 从执行器启动说起1、初始化JobHandler2、创建一个Http服务器3、注册到调度中心 任务触发原理⭐⭐⭐1、任务如何触发?调度线程scheduleThr…...

图漾相机-ROS1_SDK_ubuntu版本编译(新版本)

文章目录 官网编译文档链接官网SDK下载链接1、下载 Camport ROS1 SDK1.下载git2、下载链接 2、准备编译工作1、安装 catkin2、配置环境变量3. 将Camport3中的linux库文件拷贝到 user/lib目录下4、修改lunch文件制定相机(可以放在最后可以参考在线文档)**…...

项目二十三:电阻测量(需要简单的外围检测电路,将电阻转换为电压)测量100,1k,4.7k,10k,20k的电阻阻值,由数码管显示。要求测试误差 <10%

资料查找: 01 方案选择 使用单片机测量电阻有多种方法,以下是一些常见的方法及其原理: 串联分压法(ADC) 原理:根据串联电路的分压原理,通过测量已知电阻和待测电阻上的电压,计算出…...

【NLP 17、NLP的基础——分词】

我始终相信,世间所有的安排都有它的道理;失之东隅,收之桑榆 —— 24.12.20 一、中文分词的介绍 1.为什么讲分词? ① 分词是一个被长期研究的任务,通过了解分词算法的发展,可以看到NLP的研究历程 ② 分词…...

uniapp blob格式转换为video .mp4文件使用ffmpeg工具

前言 介绍一下这三种对象使用场景 您前端一旦涉及到文件或图片上传Q到服务器,就势必离不了 Blob/File /base64 三种主流的类型它们之间 互转 也成了常态 Blob - FileBlob -Base64Base64 - BlobFile-Base64Base64 _ File uniapp 上传文件 现在已获取到了blob格式的…...

【无标题】 [蓝桥杯 2024 省 B] 好数

[蓝桥杯 2024 省 B] 好数 好数 一个整数如果按从低位到高位的顺序,奇数位(个位、百位、万位……)上的数字是奇数,偶数位(十位、千位、十万位……)上的数字是偶数,我们就称之为“好数”。 给定一…...

Leecode刷题C语言之同位字符串连接的最小长度

执行结果:通过 执行用时和内存消耗如下&#xff1a; bool check(char *s, int m) {int n strlen(s), count0[26] {0};for (int j 0; j < n; j m) {int count1[26] {0};for (int k j; k < j m; k) {count1[s[k] - a];}if (j > 0 && memcmp(count0, cou…...

Pytorch | 利用BIM/I-FGSM针对CIFAR10上的ResNet分类器进行对抗攻击

Pytorch | 利用BIM/I-FGSM针对CIFAR10上的ResNet分类器进行对抗攻击 CIFAR数据集BIM介绍基本原理算法流程特点应用场景 BIM代码实现BIM算法实现攻击效果 代码汇总bim.pytrain.pyadvtest.py 之前已经针对CIFAR10训练了多种分类器&#xff1a; Pytorch | 从零构建AlexNet对CIFAR1…...

音频进阶学习八——傅里叶变换的介绍

文章目录 前言一、傅里叶变换1.傅里叶变换的发展2.常见的傅里叶变换3.频域 二、欧拉公式1.实数、虚数、复数2.对虚数和复数的理解3.复平面4.复数和三角函数5.复数的运算6.欧拉公式 三、积分运算1.定积分2.不定积分3.基本的积分公式4.积分规则线性替换法分部积分法 5.定积分计算…...

将4G太阳能无线监控的视频接入电子监控大屏,要考虑哪些方面?

随着科技的飞速发展&#xff0c;4G太阳能无线监控系统以其独特的优势在远程监控领域脱颖而出。这种系统结合了太阳能供电的环保特性和4G无线传输的便捷性&#xff0c;为各种环境尤其是无电或电网不稳定的地区提供了一种高效、可靠的视频监控解决方案。将这些视频流接入大屏显示…...

使用docker拉取镜像很慢或者总是超时的问题

在拉取镜像的时候比如说mysql镜像&#xff0c;在拉取 时总是失败&#xff1a; 像这种就是网络的原因&#xff0c;因为你是连接到了外网去进行下载的&#xff0c;这个时候可以添加你的访问镜像源。也就是daemon.json文件&#xff0c;如果你没有这个文件可以输入 vim /etc/dock…...

Redis数据库笔记

Spring cache 缓存的介绍 在springboot中如何使用redis的缓存 1、使用Cacheable的例子【一般都是在查询的方法上】 /*** 移动端的套餐查询* value 就是缓存的名称* key 就是缓存id &#xff0c;就是一个缓存名称下有多个缓存&#xff0c;根据id来区分* 这个id一般就是多个查询…...