【自定义View系列】导致View树重新遍历的时机

284人阅读 评论(0) 收藏 举报
分类:

  遍历View树就意味着整个View需要重新对其包含的子视图分配大小并重绘。导致重新遍历的原因主要有三个:
1. 视图本身内部状态变化引起重绘。
2. View树内部添加或者删除了View。
3. View本身的大小及可见性发生变化。

状态的分类

这里写图片描述

  在View视图中定义了多种和界面效果相关的状态。不同的状态一般会显示不同的界面效果,有多种操作会引起这些状态的改变。Android中应用程序是按照消息机制执行的,每次处理一个消息,如果该消息引起状态改变,则代码中仅仅做一些状态标识,然后发送一个异步消息,而不是立即重绘。然后在下一次消息处理中,根据保存的状态数据,绘制不同的界面效果。

  视图中和显示效果相关的状态一共有15种 —— android.graphics.drawable.StateListDrawable类中定义。

selected和focused的区别

  一个窗口中只能有一个视图获得焦点,当用户按键时,获取焦点的视图会变得高亮起来,而一个窗口可以有多个视图处于selected状态。
  按键消息最终会传递到focused视图中,而不是selected视图中。
当某个视图处于pressed状态时,如果将其selected状态设为false,那么该视图的pressed状态就会被清空。
focused状态一般是由按键操作引起的,pressed状态是由触摸消息引起的,selected则完全是由应用程序主动调用 setSlected()进行控制。
当视图重绘时,会根据当前不同的状态选择不同的背景图(selector来定义背景时)。

导致View树重新遍历的总体诱因

导致视图大小发生变化 —— invalidate()
导致ViewGroup重新为子视图分配位置 —— requestLayout()
视图显示情况发生变化需要重绘 —— requestFocus()
这三个函数最终都会调用到ViewRoot中的 schueduleTraversals()函数,该函数会发起一个异步消息,消息处理中调用 performTraversals()开始对整个View进行重新遍历。

invalidate()

能导致调用invalidate()函数的包括三种情况:
1. 调用setVisibility():当应用程序改变视图显示属性时。
2. setSelected():当改变视图Selected状态时。
3. setEnable():当改变视图Enable状态时。

requestLayout()

导致调用requestLayout()函数的情况包括两种:
1. setVisibility(),当应用程序改变视图显示属性时,由于显示或者不显示将影响其他同级视图的位置。
2. 应用程序直接或间接调用到该函数,间接调用是指应用程序调用了View类的其他函数,从而简介调用到requestLayout()。

requestFocus()

一般由程序直接调用,简介调用是指当用户按”上/下”、”左/右”键时,相关的处理逻辑会间接的调用到该函数。

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    写给自己
    ○ 种一棵树最好的时间是十年前,其次是现在

    ○ 坚持输出,坚持书写,才可以持续成长

    ○ 所有美好事物的成长都是缓慢的

    ○ 既往不恋,未来不迎,当下不杂

    ○ 业精于勤,荒于嬉,行成于思,毁于随

    ○将军赶路 不追小兔

    ○不要拘泥于语言,同样也不要拘泥于行业,眼光放远一点

    ○ 如果某件事你做的不够好,不必介怀,因为以后的每一次每一天你都会做得越来越好

    ○ 此心不于事上磨,更于何处磨此心

    ○ 保持热情,保持求知欲

    ○ 千里之行,始于足下

    ○ 最怕你一生碌碌无为,还安慰自己平凡可贵。

    ○ 对于任何事,要保持自觉积极主动探索尝试。但是如果自己不积极认真地生活,不管得到什么样的回答都没有用。——解忧杂货店
    个人资料
    • 访问:606084次
    • 积分:8399
    • 等级:
    • 排名:第2521名
    • 原创:354篇
    • 转载:61篇
    • 译文:0篇
    • 评论:140条
    个人简介