关于android自定义View的requestLauout和invalidate我一直有个疑问

查询百度,会有下面的解释
requestLayout:会调用onMeasure onLayout
invalidate:会调用onDraw

问题1:为什么我自定义的View,我在调用requestLayout时依然会调用onDraw这个方法
问题2:为什么我调用invalidate(rect)进行局部刷新时会重新走一遍onDraw的所有方法,而不是只走对应的局部方法,这样的话和invalidate就没有区别了啊?

问题3:在自定义ViewGroup时,在init时new出一个View并add上去,调用ViewGroup的requestLayout方法后,发现没有调用这个View的onMeasure方法,或者调用ViewGroup的invalidate后,发现没有调用子View的onDraw方法。

这些问题都是为什么?请相关大牛帮忙细心解释。

3个回答

问题1:
调用requestLayout申请重新布局后是肯定会调用View的onDraw()跟ViewGroup的dispatchDraw()
只有在如下几种情况下不调用:
1、View 不用显示的时候,包含两种情况:
view的Visibility属性不为View.VISIBLE
view设置了OnPreDrawListener,并在onPreDraw里返回了false
2、app还没启动完成正在创建Surface的时候
3、Window窗口正在跑动画的时候不会调用,但是requestLayout的请求在窗口动画第一帧之前会调用一次

问题2:
invalidate(rect),里的rect是用来锁定View在画布上的可更新区域的
源码ViewRootImpl.java里的drawSoftware函数里有如下代码
canvas = mSurface.lockCanvas(dirty);
你传不传rect只影响画布上的可更新区域,不会影响onDraw的调用逻辑

问题3:
调用requestLayout申请重新布局后,肯定是会调用该View的onMeasure方法,以及该View的所有父View的onMeasure方法
对于该View的子View,如果Size发生变化则也会调用onMeasure方法,否则是不会掉的
所以你调用了父View的requestLayout方法,如果子View的size没有发生变化,是不会调用它的onMeasure方法
调用ViewGroup的invalidate后,子view肯定也是重新绘制的,只是不是通过onDraw来更新,View是有缓存的,内容没有更新的时候是不需要调用onDraw函数的

Z_dong_dong
Z_dong_dong 多谢细心解答。
大约 2 年之前 回复

问题1的回答,我觉得你应该好好看看绘制过程的调用的方法,类似于生命周期的一个过程.

1、绘制流程大体分为 "3部分", ① onMeasure ②onLayout ③ onDraw , 在 requestLayout中 会依次进行 onMeasure->onLayout->onDraw方法的调用。
2、invalidate(脏区),依然会走onDraw, 只不过你绘制的时候 会只针对Rect(脏区)内的 内容进行局部刷新,其他地方不会。
3. 调用ViewGroup 的requestLayout, 只是走了ViewGroup的 方法,而并没有去 绘制子View,具体一些逻辑可查看源码分析。

Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!