activitythread里面的resume,
获取 WindowManager(桥接模式,核心方法不想暴露出来,用一个中间类持有核心类成员,中间类类可以访问核心类方法暴露给用户调用),
用wm. addview方法
通过viewRootImpl添加decorView
并开始调用requestLayout开始请求布局
requestLayout会检测当前线程是否在主线程,所以view更新ui要在onResume之前完成
requestlayout通过handler发送消息去遍历viewTree
requestLayout会重新刷新 测量,布局,绘制。但是只有当view以及子view的位置或大小发生变化的时候才会执行绘制。
invalidate只会在UI线程调用绘制方法,postInvalidate可以在非UI线程中调用
MeasureSpec是32位,前2位是模式(match_parent,wrap_content),后30位是容器的大小值
unspecified:父view不对子view有任何限制,子view需要多大就有多大。
exactly:父View已经测量出子view所需要的精确大小,这个时候view的最终大小就是SpecSize所值的职位,对应于match_parent和精确值两种。
at_most:子view的最终大小是父View指定的SpecSize值,并且子View的大小不能大于这个值,对应于wrap_content这种模式。
测量一步一步往子view去测量,根据子view的大小确定父容器的宽高,例如specMode为unspecified,该view的大小由于specSize决定。如果为at_most,那么会一步一步往子view测量计算宽高,如果不超过specSize,那么就是这次测量的宽高,如果超过了specSize,那么就是specSize的值。
MeasureSpec的数值来源,DecorView由窗口的尺寸和其自身的LayoutParams共同来决定,普通view由父容器和自身的Layoutparams共同来决定。
=================onDraw里面涉及到的知识=================
图形绘制画笔Paint
Paint主要有渲染、滤镜、Xfermode等重要知识要了解
渲染
Shader:着色器
- Canvas的drawXXXX画具体形状,Paint的shader定义的就是图形的着色和外观。
- TileMode:拉升形式
1.CLAMP:是拉升最后一个像素铺满
2.REPEAT:类似电脑壁纸,横向纵向不足的重复放置
3.MIRROR:在横向纵向不足处不断翻转镜像平铺
BitmapShader:位图渲染
- 用BitMap对绘制的图形进行渲染着色,简单来说是用图片对图形进行贴图。(圆形头像、放大镜效果)
LinearGradient: 线性渲染
- 用于图形元素的填充或描边。(歌词显示)
SweepGradient: 扫描渲染
RadialGradient: 环形渲染
ComposeShader: 组合渲染
滤镜
对原有图像色彩进行调整
- 颜色模式:是将某种颜色表现为数字形式的模型,或者说是一种记录图像颜色的方式。
主要分为RGB模式、CMYK模式、HSB模式、LAB颜色模式、位图模式、灰度模式、索引颜色模式、双色调模式和多通道模式 - 颜色通道:
一个像素的颜色由四个分量组成,其中A为透明通道、R为红色通道、G为绿色通道、B为蓝色通道。像素点通道值越大像素点所占颜色比列越多。 -
颜色矩阵
通过矩阵与矩阵的相乘等运算从而改变矩阵值
image.png - setMaskFilter设置滤镜
1.BlurMaskFilter模糊遮罩滤镜
2.EmbossMaskFilter浮雕遮罩滤镜;绘制的图像感觉像是从屏幕中“凸”起来更有立体感一样(在设计软件中类似的效果称之为斜面浮雕)
**硬件加速会看不到效果,所以需要关闭硬件加速
Xfermode
通过使用Xfermode能够完成图像组合的效果(通过两张图的组合生成一张图)
- PorterDuff.Mode混合模式 API文档
Canvas
字面翻译“画布”,本质其实是一个绘制图形的工具
坐标体系:默认零点位于屏幕左上角
- 画图分析:两种坐标系:
1.canvas坐标系(最外层画板,一经确定就不会改变)
2.绘图坐标系:修改坐标后不可逆。 - 主要方法
1.Canvas.save() ,保存画布,将所有已经绘制的图像保存起来,让后续的操作就像在新得图层上面操作一样。
2.Canvas.restore(),合并图层操作,将save()之后绘制的所有图像与save()之间的图像进行合并。
3.Canvas.translate(),绘图坐标的平移。
4.Canvas.rotare(),绘制图标的翻转。
5.运算方式,Matrix变换矩阵
图层概念
- 状态栈:save、restore方法来保存和还原变换操作Matrix以及Clip裁剪,也可以通过restoretoCount直接还原到对应的保存状态。
-
layer栈:saveLayer的时候都会新建一个透明的图层(离屏Bitmap-离屏缓冲),并且会将saveLayer之前的一些Canvas操作延续过来,后续的绘图操作都在新建的layer上面进行,当我们调用restore或者restoreToCount时,更新到对应的图层和画布上。image.png
PathMeasure获取path相关属性负责类,轨迹动画使用
view的事件分发机制
1 整体流程
linux/设备 -> 推送消息 -> dev/input(文件系统) ->
InputManager(EventHub -> 信息加工 -> inputReaderThread -> 事件传递 -> InputDispatcherThread)-> (socketpair)-> ViewRootImpl -> JNI -> IMS -> WMS
- 事件分发涉及到onTouch,onTouchEvent,onClick事件,onTouch返回为true的话onClick就不会收到回调
- 事件分发涉及到两个方法,一个dispatchTouchEvent,一个onInterceptTouchEvent,一个分发一个拦截。
dispatchTouchEvent发送事件,由onInterceptTouchEvent确认是否拦截,true则拦截自己处理onTouchEvent事件,fasle则不拦截让他继续发送事件。拦截后生成一条tag链路,以后事件只发送给这条链路 - dispatchTouchEvent从activity->phoneWindow->DecorView->viewGroup->view。相应的如果需要拦截则处理onInterceptTouchEvent返回事件,注意view中没有onInterceptTouchEvent方法。
- 我们处理滑动冲突事件一般会遇到两种情况,一种同向滑动,一种非同向滑动,同向滑动可能需要用到behave处理。非同向滑动则需要我们根据相应的角度去处理滑动冲突事件。
- 滑动冲突事件根据滑动角度确认是否拦截,主要处理方案有两种,一种外部拦截,一种内部拦截。
外部拦截相对简单一些,就是外层view直接重写onInterceptTouchEvent,然后根据事件的角度确认是否需要拦截。 - 某些情况下外部拦截无法处理的时候需要使用内部拦截,内部拦截就是子容器发送事件给父容器getParent.requestDisallowInterceptTouchEventb不要拦截,我来处理。

