android坐标2

2024-06-19 09:58
文章标签 android 坐标

本文主要是介绍android坐标2,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

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


(一)首先明确一下 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~获取view在屏幕中的位置

getLocalVisibleRect , 返回一个填充的Rect对象, 感觉是这个View的Rect大小,left,top取到的都是0

getGlobalVisibleRect , 获取全局坐标系的一个视图区域, 返回一个填充的Rect对象;该Rect是基于总整个屏幕的

getLocationOnScreen ,计算该视图在全局坐标系中的x,y值,(注意这个值是要从屏幕顶端算起,也就是索包括了通知栏的高度)//获取在当前屏幕内的绝对坐标 

getLocationInWindow ,计算该视图在它所在的widnow的坐标x,y值,//获取在整个窗口内的绝对坐标 (不是很理解= =、)

getLeft , getTopgetBottomgetRight,  这一组是获取相对在它父亲里的坐标

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

example:

    int[] location = new int[2];
    v.getLocationOnScreen(location);
    int x = location[0];
    int y = location[1];

这篇关于android坐标2的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1074707

相关文章

Java五子棋之坐标校正

上篇针对了Java项目中的解构思维,在这篇内容中我们不妨从整体项目中拆解拿出一个非常重要的五子棋逻辑实现:坐标校正,我们如何使漫无目的鼠标点击变得有序化和可控化呢? 目录 一、从鼠标监听到获取坐标 1.MouseListener和MouseAdapter 2.mousePressed方法 二、坐标校正的具体实现方法 1.关于fillOval方法 2.坐标获取 3.坐标转换 4.坐

计算绕原点旋转某角度后的点的坐标

问题: A点(x, y)按顺时针旋转 theta 角度后点的坐标为A1点(x1,y1)  ,求x1 y1坐标用(x,y)和 theta 来表示 方法一: 设 OA 向量和x轴的角度为 alpha , 那么顺时针转过 theta后 ,OA1 向量和x轴的角度为 (alpha - theta) 。 使用圆的参数方程来表示点坐标。A的坐标可以表示为: \[\left\{ {\begin{ar

Eclipse+ADT与Android Studio开发的区别

下文的EA指Eclipse+ADT,AS就是指Android Studio。 就编写界面布局来说AS可以边开发边预览(所见即所得,以及多个屏幕预览),这个优势比较大。AS运行时占的内存比EA的要小。AS创建项目时要创建gradle项目框架,so,创建项目时AS比较慢。android studio基于gradle构建项目,你无法同时集中管理和维护多个项目的源码,而eclipse ADT可以同时打开

android 免费短信验证功能

没有太复杂的使用的话,功能实现比较简单粗暴。 在www.mob.com网站中可以申请使用免费短信验证功能。 步骤: 1.注册登录。 2.选择“短信验证码SDK” 3.下载对应的sdk包,我这是选studio的。 4.从头像那进入后台并创建短信验证应用,获取到key跟secret 5.根据技术文档操作(initSDK方法写在setContentView上面) 6.关键:在有用到的Mo

android一键分享功能部分实现

为什么叫做部分实现呢,其实是我只实现一部分的分享。如新浪微博,那还有没去实现的是微信分享。还有一部分奇怪的问题:我QQ分享跟QQ空间的分享功能,我都没配置key那些都是原本集成就有的key也可以实现分享,谁清楚的麻烦详解下。 实现分享功能我们可以去www.mob.com这个网站集成。免费的,而且还有短信验证功能。等这分享研究完后就研究下短信验证功能。 开始实现步骤(新浪分享,以下是本人自己实现

Android我的二维码扫描功能发展史(完整)

最近在研究下二维码扫描功能,跟据从网上查阅的资料到自己勉强已实现扫描功能来一一介绍我的二维码扫描功能实现的发展历程: 首页通过网络搜索发现做android二维码扫描功能看去都是基于google的ZXing项目开发。 2、搜索怎么使用ZXing实现自己的二维码扫描:从网上下载ZXing-2.2.zip以及core-2.2-source.jar文件,分别解压两个文件。然后把.jar解压出来的整个c

android 带与不带logo的二维码生成

该代码基于ZXing项目,这个网上能下载得到。 定义的控件以及属性: public static final int SCAN_CODE = 1;private ImageView iv;private EditText et;private Button qr_btn,add_logo;private Bitmap logo,bitmap,bmp; //logo图标private st

Android多线程下载见解

通过for循环开启N个线程,这是多线程,但每次循环都new一个线程肯定很耗内存的。那可以改用线程池来。 就以我个人对多线程下载的理解是开启一个线程后: 1.通过HttpUrlConnection对象获取要下载文件的总长度 2.通过RandomAccessFile流对象在本地创建一个跟远程文件长度一样大小的空文件。 3.通过文件总长度/线程个数=得到每个线程大概要下载的量(线程块大小)。

时间服务器中,适用于国内的 NTP 服务器地址,可用于时间同步或 Android 加速 GPS 定位

NTP 是什么?   NTP 是网络时间协议(Network Time Protocol),它用来同步网络设备【如计算机、手机】的时间的协议。 NTP 实现什么目的?   目的很简单,就是为了提供准确时间。因为我们的手表、设备等,经常会时间跑着跑着就有误差,或快或慢的少几秒,时间长了甚至误差过分钟。 NTP 服务器列表 最常见、熟知的就是 www.pool.ntp.org/zo

高仿精仿愤怒的小鸟android版游戏源码

这是一款很完美的高仿精仿愤怒的小鸟android版游戏源码,大家可以研究一下吧、 为了报复偷走鸟蛋的肥猪们,鸟儿以自己的身体为武器,仿佛炮弹一样去攻击肥猪们的堡垒。游戏是十分卡通的2D画面,看着愤怒的红色小鸟,奋不顾身的往绿色的肥猪的堡垒砸去,那种奇妙的感觉还真是令人感到很欢乐。而游戏的配乐同样充满了欢乐的感觉,轻松的节奏,欢快的风格。 源码下载