Android 中的坐标视图体系
1、Android 坐标系:
系统提供了 getLocationOnScreen(int location[ ]) 这样的方法来获取 Android 坐标系中点的坐标,等效于在触摸事件中使用 getRawX() 、getRawY()方法,获取的是绝对坐标,坐标原点是屏幕的左上角
2、视图坐标系:
在触摸事件中,通过getX()、getY()来获取坐标位置,坐标原点是以父视图左上角为坐标原点。
3、触摸事件(MotionEvent):
MotionEcent中封装了以下触摸事件的不同类型常量
//单点触摸按下动作 public static final int ACTION_DOWN = 0; //单点触摸离开动作 public static final int ACTION_UP = 1; //触摸点移动操作 public static final int ACTION_MOVE = 2; //触摸动作取消 public static final int ACTION_CANCEL = 3; //触摸动作超出边界 public static final int ACTION_OUTSIDE = 4; //多点触摸按下动作 public static final int ACTION_POINTER_DOWN = 5; //多点离开动作 public static final int ACTION_POINTER_UP = 6;
4、View提供的获取坐标方法(相对父容器的):
getTop():获取到的是View自身的顶边到其父布局顶边的距离
getLeft():获取到的是View自身的左边到其父布局顶边的距离
getRight():
获取到的是View自身的右边到其父布局顶边的距离
getBottom():
获取到的是View自身的底边到其父布局顶边的距离
5、MotionEvent 提供的方法:
getX():获取点击事件距离控件左边的距离,即视图坐标(相对父容器的)
getY():获取点击事件距离控件顶边的距离,即视图坐标(相对父容器的)
getRawX():获取点击事件距离整个屏幕左边的距离,即绝对坐标(相对屏幕的)
getRawY():获取点击事件距离整个屏幕顶边的距离,即绝对坐标(相对屏幕的)
从上我们能够的出 View 的宽高和坐标的关系:
width = right - left;
height = bottom - top;
这四个参数可从以下方式获取:
left = getLeft();
right = getRitht;
top = getTop;
bottom = getBottom;
从Android3.0开始,另外还有几个参数:x、y、translationX 和 translationY。
x、y是VIew左上角的坐标,translationX 和 translationY 是View左上角相对于父容器的偏移量。默认为0。
且 x = left + translationX,y = top + translationY
就是说在View平移的过程中,top、left、right、button这四个值是不会变化的,是原始位置,变化的是x、y、translationX 和 translationY这四个参数。
6、TouchSlop 系统能识别的最小滑动距离(一般为8dp,因设备而不同),可过滤一些滑动操作
获取方式:ViewConfiguration.get(getContext()).getScaledTouchSlop()
其中的get是为了获取一个ViewConfiguration类型的对象,然后这个对象再调用getScaledTouchSlop方法。
而它的默认值是定义在这里的:
里面的config.xml中:
<!-- Base "touch slop" value used by ViewConfiguration as a movement threshold where scrolling should begin. --> <dimen name="config_viewConfigurationTouchSlop">8dp</dimen>
Android 控件架构
概念:
Android中所有控件在界面中占得位置均是矩形,分为ViewGroup和View,通过ViewGoup使整个界面形成了一个树形结构,由上层控件负责下层子控件的测量和绘制,并传递交互事件。每棵树控件的顶部,都有一个ViewParent对象,是整颗树的核心,所有交互管理事件都是由它来统一调度和分配,从而可以对整个视图进行整体控制
Android 控件继承结构图:
Android 控件树结构图:
ViewGoup:可包含多个子控件,并管理其包含的子控件
ViewParent:控件树的核心,调度和分配所有的交互管理事件
由上图可看出,每个Activity中都包含一个Window对象,在Android中Wiondw对象通常由PhoneWindow来实现。
PhoneWindow
:
将一个DecorView设置为整个应用窗口的根View,
是Window的具体继承实现类。而且该类内部包含了一个
DecorView对象,该DectorView对象是所有应用窗口(Activity界面)的根View。
来
显示具体的界面内容
DecorView:窗口界面的顶层视图,里面封装了一些窗口操作的通用方法,其把将要显示的具体内容呈现在了PhoneWindow上,在此所有的View的事件监听,都通过
WindowManagerService(窗口管理服务,所有需要显示到屏幕上的内容,都是通过WMS 来操控的,可见设计模式中的Builder 模式和点击打开链接)来进行接收,并通过Activity对象来回调相应的onClickListener。
依据面向对象从抽象到具体我们可以类比上面关系就像如下:
Window是一块电子屏,PhoneWindow是一块手机电子屏,DecorView就是电子屏要显示的内容,Activity就是手机电子屏安装位置。
在显示上,DecorView将屏幕分为
TitleView和
ContentView两部分。
ContentView:是
一个ID为content的FrameLayout,
activity_main.xml就是设置在这样一个FramLayout中的。
DocrView标准视图树:
视图树的第二层装载了一个LinearLayout,作为ViewGroup,这一层的布局结构会根据对应的参数设置不同的布局,如最常用的布局--上面显示TitleBar下面是Content这样的布局,也就是上图的布局。
如果用户通过设置requestWindowFeature(Window.FEATURE_NO_TITLE)来设置全屏显示,视图树中就只有Content了,
所以requestWindowFeature() 方法一定要在调用setContentView()方法之前。
-
在代码中,当程序在onCreat()方法中调用setContentView()方法后,ActivityManagerService会回调 onResume()方法,此时系统会把整个 DocrView添加到 PhoneWindow中,并让其显示出来。