flex失效机制,看了一遍没看懂。先占下来

来源:互联网 发布:足下软件学院分数线 编辑:程序博客网 时间:2024/04/28 21:12
FLEX组件的失效机制由
IInvalidating ILayoutManagerClient和
实现了ILayoutManager的LayoutManager
以及UIComponent中的commitProperties()、measure()、updateDisplayList()完成


IInvalidating 接口定义了
invalidateProperties、
invalidateSize、
invalidateDisplayList、
validateNow




ILayoutManagerClient 接口定义了
validateProperties、
validateSize、
validateDisplayList




ILayoutManager 接口定义的主要方法有
invalidateProperties、
invalidateSize、
invalidateDisplayList、
validateNow、
validateClient方法
名字看上去跟IInvalidating 接口的一样
区别在于ILayoutManager 的方法有一个ILayoutManagerClient参数需要传入




下面来说一下 他们是怎么协调工作并达到延迟更新组件的效果
以Label组件更改text属性为例当设置text属性之后代码的执行 我按代码执行顺序来说




喜欢0
游客
matt
matt
新手
新手
  • UID2
  • 粉丝0
  • 关注0
  • 发帖数13
加关注写私信
沙发#
发布于:2013-01-31 15:22
Label组件
首先 1、Label组调用IInvalidating接口中的invalidateProperties方法
      2、在invalidateProperties中程序会调用layoutManager的invalidateProperties并将自身传入
      3、layoutManager将label加入到invalidatePropertiesQueue这个优先队列里面(layoutManager弟213行)关于属性部分到这里暂时结束了




然后  1、Label组件调用IInvalidating接口中invalidateSize方法
      2、在invalidateSize方法中程序会调用layoutManager的invalidateSize并将自身传入
      3、layoutManager将label加入到invalidateSizeQueue这个优先队列里面(layoutManager弟236行)关于属性组件size到这里暂时结束了




最后  1、Label组件调用IInvalidating接口中invalidateDisplayList方法
      2、在invalidateDisplayList方法中程序会调用layoutManager的invalidateDisplayList并将自身传入
      3、layoutManager将label加入到invalidateDisplayListQueue这个优先队列里面(layoutManager弟259行)关于属性组件的布局和绘制到这里暂时结束了






回复喜欢
matt
matt
新手
新手
  • UID2
  • 粉丝0
  • 关注0
  • 发帖数13
加关注写私信
板凳#
发布于:2013-01-31 15:23
当Label组件的这些操作做完之后 屏幕上呈现出来的画面并没有改变
因为layoutManager将这些更改延迟到了下一次屏幕更新的时候
当layoutManager的invalidate系列方法被调用的时候
layoutManager都会检测自己是否添加了Event.ENTER_FRAME事件
(参见LayoutManager弟450、501、538行)如果没有添加会马上添加上 ,
当下一次屏幕更新到来的时候
1、LayoutManager会调用doPhasedInstantiationCallback(1168行)方法也就是    
   Event.ENTER_FRAME的handler
2、然后在再调用doPhasedInstantiation函数(777行)
3、doPhasedInstantiation函数会按顺序执行LayoutManager 的
   validateProperties(571行)、
   validateSize(642行)、
   validateDisplayList(713行)3个方法,(程序会进行一些判断)




大家应该还记得在Label组件在调用layoutManager的invalidate系列方法的时候会将自身传入也就是传入了一个ILayoutManagerClient 接口而LayoutManager 会将其存入一个优先队列中 所以现在 当LayoutManager 调用在自己的 validateProperties、validateSize、validateDisplayList方法的时候 这3个函数会分别从对应的优先队列中取出ILayoutManagerClient 对象并调用他们的validateProperties、validateSize、validateDisplayList方法

回复喜欢
matt
matt
新手
新手
  • UID2
  • 粉丝0
  • 关注0
  • 发帖数13
加关注写私信
地板#
发布于:2013-01-31 15:23

上面说到了优先队列 所以这些优先队列中对象的函数调用肯定会有一个顺序的问题
在说这个顺序之前先说一下FLASH的显示列表...


FLASH的显示对象由displayobject而来 而displayObjectContainer是显示对象的容器
FLASH的显示列表使用Composite模式创建 看到这个模式首先想到的应该是一个树形结构 在这个树形结构中displayObjectContainer做为树的非叶子节点displayobject为叶子节点
stage对象是一个displayObjectContainer是一个根节点

举个例子 舞台上有一个Sprite和一个Container然后Container里面有一个Shape一个Bitmap一个Sprite 这样他们的关系就是


stage |- >   Sprite
          |- >   Container |- >Shape
                                   |- > Bitmap
                                   | - > Sprite


从上面的关系可以知道 有了这个树形结构就很容易设置他们的深度 ,至于这个树形结构的其他用途暂时不去考虑
而ILayoutManagerClient 正是通过这个树形结构设置了每个组件的nestLevel属性 这个属性被优先队列用来排序
说到这里 排序的问题OK了
继续说validateProperties、validateSize、validateDisplayList这3个方法  他们的顺序分别是


validateProperties 是自上而下的 (可能是考虑到父组件会改变子组件的属性)


validateSize 是自下而上的(自组件的大小会影响到父组件 很多组件在测量阶段都会用到子组件的size)


validateDisplayList是自上而下(一层盖一层)


上面说道这3个函数会分别从对应的优先队列中取出ILayoutManagerClient 对象并调用他们的validateProperties、validateSize、validateDisplayList方法
在实现了ILayoutManagerClient接口的组件中 这个3个方法又分别调用了commitProperties()、measure() 、 updateDisplayList()


而这3个方法就是我们自定义组件时候最常用的3个方法
其中measure方法比较特殊 它是用来设计默认大小的
一旦你为组件显示的指定了大小这个函数就不会再执行
即使调用了invalidateSize方法也不会执行
回复喜欢
matt
matt
新手
新手
  • UID2
  • 粉丝0
  • 关注0
  • 发帖数13
加关注写私信
4楼#
发布于:2013-01-31 15:23
总结:
自定义显示组件的时候
影响到组件显示状态的属性
要在set里面调用invalidateProperties方法
然后在commitProperties方法里面验证属性的正确性如果不正确设置一个新的值


例如


设置的宽度小于组件的最小宽度 如果小于就设置为最小宽度
然后再调用invalidateDisplayList方法
在updateDisplayList中进行组件的绘制布局
在updateDisplayList不要用height width属性
一定要用unscaledWidth unscaledHeight因为你无法确定组件是否被用户缩放
所以用没有缩放的宽高比较靠谱
原创粉丝点击