码农-虚无吞炎 2017-09-20 05:11 采纳率: 0%
浏览 1328
已采纳

关于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条回答 默认 最新

  • Tauren2614 2017-09-20 11:42
    关注

    问题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函数的

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(2条)

报告相同问题?

悬赏问题

  • ¥15 关于#vscode#的问题:ESP32开发板对接MQTT实现小灯泡的开关
  • ¥15 TMC2209串口模式下读取不到寄存器的值串口助手蓝色字体是发过去的消息,绿色字体是收到的消息,第二行发送读取寄存器的指令但是没有读取到寄存器的值串口助手如下图:接线如下图,如何解决?
  • ¥15 高通安卓11提取完整线刷包软件,或者优博讯dt50顺丰刷机包
  • ¥20 C,有个译码器,换了信道就跑不出原来数据
  • ¥15 MIMIC数据库安装问题
  • ¥60 基于JTag协议开发Fpga下载器上位机,哪位大🐂有偿指导?
  • ¥20 全书网Java爬取数据
  • ¥15 怎么获取红包封面的原始链接,并且获取红包封面序列号
  • ¥100 微信小程序跑脚本授权的问题
  • ¥100 房产抖音小程序苹果搜不到安卓可以付费悬赏