1.引言
这章的内容是View,谈起View 脑海中不禁想起,view的绘制,view的测量,view事件分发,view的三种模式,view的动画实现方式,view的二种坐标系,SurfaceView,下面就跟着书本,一一的回忆下
2.正题
2.1 android 坐标系 和 view坐标系
android坐标系
:Android坐标系将屏幕的左上角的顶点作为Android坐标系的原点,向右为X轴的正方向,向下是Y轴的正方向。在触控事件中getRawX() 和 getRawY()获得的坐标也是Android坐标系的坐标。
view坐标系
:
1 自身坐标 以下方法获得View到父控件的距离
getTop() : 获取View自身顶边到父布局顶边的距离:
getLeft() : 获取View自身左边到其父布局左边的距离;
getRight() : 获取View自身右边 到其父布局左边的距离;
getBottom() : 获取View 自身底部 到其父布局的顶边的距离;
2 MotionEvent获取触摸点坐标
如上图所示
getX(): 获取点击事件距离控件左边的距离,即视图坐标;
getY(): 获取点击事件距离控件顶边的距离,即视图坐标;
getRawX():获取点击事件距离整个屏幕左边的距离,即绝对坐标。
getRawY():获取点击事件距离整个屏幕顶边的距离,即绝对坐标。
2.1 View 滑动的三种方式
-
scrollTo/scrollBy
滑动的只是控件的内容 而非控件本身 -
动画
-
改变LayoutParams参数
2.2 postInvalidate vs invalidate
invalidate主线程刷新ui,postInvalidate 在子线程刷新ui。本质上postInvalidate方法内部,先将子线程切换到主线程,然后在调用invalidate
注意: postInvalidate 和 invalidate 并不会让view 重新测量,布局
2.3 RelativeLayout和LinearLayout性能分析
RelativeLayout性能要弱于LinearLayout 上面,主要体现在 测量上面。RelativeLayout 要对横向和纵向的子View 分别测试。但是LinearLayout 只需要对指定方向上的View 进行测量。
2.4 View 事件分发
一个点击事件起于ACTION_DOWN ,结束于ACTION_UP. 一个View 处理了ACTION_DOWN事件,那么接下来所有的事件例如move等都会交给它处理。View的分发从Activity----Window---DecorView 层层下发。ViewGroup的dispatchTouchEvent 方法中,会调用onInterceptTouchEvent方法,假如onInterceptTouchEvent返回true,那么紧接着调用onTouchEvent方法;假如onInterceptTouchEvent 返回false,那么就会调用子View. dispatchTouchEvent。假如子View是一个ViewGroup那么就会按照之前机制继续分发。假如子View是一个View,那么子View的dispatchTouchEvent中就会根据判断决定是否执行onTouchEvent方法。onTouchListener的优先级>onTouchEvent >onClickListener
2.5 DecorView 介绍
DecorView 是顶级View,本质上是一个FramLayout,内部包含一个LinerLayout, LinerLayout是竖向分布,第一部分是一个title,第二部分就是我们的contentView。
2.6 View 绘制流程
ViewRootImp是真正操作view的添加和删除的。performTraversals方法是绘制测量的入口。进而执行performMeasure,performLayout,performDraw。
-
performMeasure : ViewGroup.measureChildren()方法,通过for循环遍历child,调用measureChild方法,参数是child,parentMeasureSpec。measureChild方法中,子Child 通过自己的LayoutParams参数 和父布局的MeasureSpec 得到属于自己的MeasureSpec。进一步调用measure方法进行测量。measure方法最终会调用onMeasure方法。从这个过程中可以知道:子View的MeasureSpec 是根据自己的LayoutParams参数+ 父布局的MeasureSpec得来的。与之前的知识首位呼应
-
performLayout:
rootView(DecorView),调用layout方法,layout方法中,进而又调用了onLayout方法,onLayout是需要各父容器重写的方法,DecorView本质上是FramLayout,那么可以查看FramLayout的onLayout方法,发现会对view进行遍历,view会调用view.layout(childLeft, childTop, childLeft + width, childTop + height),进而调用onLayout方法 -
performDraw
2.7 MeasureSpec
系统将View的LayoutParams 和父容器的宽高限制结合起来,形成MeasureSpec,MeasureSpec是4个字节,32位,高俩位是用来表示测量模式。后30位表示测量大小。
测量模式:
- Unspecified(父容器对子view大小不做限制,要多少给多少)
- At most
- Exactly
网友评论