View关于坐标方法系列
相对坐标系列
MotionEvent 系列方法
-
e.getX()/e.getY()
/** * Returns the X coordinate of this event for the given pointer * <em>index</em> (use {@link #getPointerId(int)} to find the pointer * identifier for this index). * Whole numbers are pixels; the * value may have a fraction for input devices that are sub-pixel precise. * @param pointerIndex Raw index of pointer to retrieve. Value may be from 0 * (the first pointer that is down) to {@link #getPointerCount()}-1. * * @see #AXIS_X */触摸点相对于View自身的X,Y坐标偏移量。
View 系列方法
-
view.getTop()/getLeft()/getRight()/getBottom()
/** * Left position of this view relative to its parent. * * @return The left edge of this view, in pixels. */得到的坐标是view相对于其父容器的坐标,也即是view在父容器中的绘制区域。实际上right-left 与bottom-top正好是view的width与height
以父容器的左上角为坐标原点
具体测试代码结果下文有贴入,这里简单描述一下结果。
revenueLayout的top为100,恰好是其相对父容器的一个margin值;tvProfit的top为15,恰好是其父容器revenueLayout的padding大小。
-
view.getTranslationX()/getTranslationY()
/** * The vertical location of this view relative to its {@link #getTop() top} position. * This position is post-layout, in addition to wherever the object's * layout placed it. * * @return The vertical position of this view relative to its top position, * in pixels. */得到的值是其相对于初始的left or top 的平移距离,,这个与属性动画中的translation设置有关系
绝对坐标系列
以屏幕的左上角为坐标原点
View系列方法
-
view.getLocationInWindow(@Size(2) int[] outLocation)
/** * <p>Computes the coordinates of this view in its window. The argument * must be an array of two integers. After the method returns, the array * contains the x and y location in that order.</p> * * @param outLocation an array of two integers in which to hold the coordinates */获取当前view在Window中的坐标,也即是window的绝对坐标
-
view.getLocationOnScreen(@Size(2) int[] outLocation)
/** * <p>Computes the coordinates of this view on the screen. The argument * must be an array of two integers. After the method returns, the array * contains the x and y location in that order.</p> * * @param outLocation an array of two integers in which to hold the coordinates */与getLocationInWindow()的返回相同,下面的测试结果中也验证了是相同。具体是不是存在特殊的差异,还未发现
-
view.getGlobalVisibleRect(Rect r)/getGlobalVisibleRect(Rect r, Point globalOffset)
/** * If some part of this view is not clipped by any of its parents, then * return that area in r in global (root) coordinates. To convert r to local * coordinates (without taking possible View rotations into account), offset * it by -globalOffset (e.g. r.offset(-globalOffset.x, -globalOffset.y)). * If the view is completely clipped or translated out, return false. * * @param r If true is returned, r holds the global coordinates of the * visible portion of this view. * @param globalOffset If true is returned, globalOffset holds the dx,dy * between this view and its root. globalOffet may be null. * @return true if r is non-empty (i.e. part of the view is visible at the * root level. */获取当前view在绝对坐标系中的rect对象,也即是绘制区域的绝对坐标边界。
MotionEvent 系列方法
-
e.getRawX()/e.getRawY()
/** * Returns the original raw X coordinate of this event. For touch * events on the screen, this is the original location of the event * on the screen, before it had been adjusted for the containing window * and views. * * @see #getX(int) * @see #AXIS_X */触摸点相对于屏幕原点的x,y坐标。
测试案例
机型信息如下:
device_info.png
布局文件View位置
<RelativeLayout
android:layout_marginTop="100px"
android:id="@+id/revenue_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="15px">
<TextView
android:id="@+id/tv_balance"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="余额:0 元"
android:textSize="12dp" />
<TextView
android:id="@+id/tv_profit"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:text="据历史收益可得:0.00 元"
android:textSize="12dp" />
</RelativeLayout>
预览截图如下:
xml_preview.png
onResume()中执行结果:
location_onresume.png
onResume中并没有获取到View坐标信息
onWindowFocusChanged()中执行结果:
activity 应用全屏主题(NoTitle)
location_notitle.png
activity 为应用全屏主题(有actionbar)
location_actionbar.png
从上述两个运行结果来看,getLocationInWindow()与getLocationOnScreen()并未存在差异。
其中tvBalance的position [15,169],Y坐标169是100(revenueLayout的margin)+15(revenueLayout的padding)+54(状态栏status bar的高度,此值是反推出来的)。由此就可以看出获取的确实是View的绝对坐标。
而对于应用非全屏(NoTitle)主题的结果,position [15,337],恰好就是多出了一个actionbar的高度,即337-169 = 168。而168恰好满足56*3(density),这里就看到了,在系统默认的配置下当前的屏幕宽度下,actionbar的高度为56dp,当前的density恰好是3.0,而换算成px就是168。到了这里,整个测试结果就完全验证了,上述方法的解释。
备注:
- View的坐标体系在OnCreate()中还未进行初始化,所以onCreate中无法获取View的相关坐标,都是return 0;
- View的坐标在onWindowFocusChanged(true)时,才会初始化完毕,故在此方法的回调是获取View坐标的最佳之处。
- 由于onResume与onWindowFocusChanged的调用时机的不同,在第一次执行onResume时也无法直接获取到View的坐标。








网友评论