Flex样式工作原理分析 Part Two(完结)
作者:admin 日期:2008-09-08
以下分析都从flex3源代码推出,不一定正确!希望能和有兴趣的朋友一起探讨。
在Flex样式工作原理分析 Part One中,我们分析了组件是如何获得样式信息的,下面来谈一下设置样式是如何工作的。
每当组件需要重新设置自己的样式时(比如说调用了setStyle()方法或者设置了styleName属性),组件的styleChanged(styleProp:String)方法就会被调用,然后我们在styleChanged(styleProp:String)方法体里面根据参数styleProp的值的不同来对组件的样式做出相应的处理。那么什么时候组件的styleChanged(styleProp:String)方法会触发呢?下面介绍如下:
1,setStyle()方法
当我们调用setStyle()方法的时候,首先会调用该组件的styleChanged(styleProp)然后判断改变的样式是否是可继承样式,如果是,则调用该组件的所有子孙的styleChanged(styleProp)方法。比如:
程序代码
当我们调用 myCanvas.setStyle("color", 0xff0000)的时候,首先会重新设置该组件的样式缓存(CSS style cache),
这样调用myCanvas.getStyle("color")时就能得到值0xff0000。然后调用myCanvas.styleChanged("color"); 因为
color是可继承样式,所以会接着调用box.styleChanged("color"),text1.styleChanged("color"),text2.styleChanged("color"),text3.styleChanged("color"),text4.styleChanged("color"),myBtn.styleChanged("color");
当我们调用 myCanvas.setStyle("backgroundColor", 0xff0000)的时候,首先调用myCanvas.styleChanged("backgroundColor")因为backgroundColor不是可继承样式,所以myCanvas的子孙的styleChanged(styleProp)方法不会被调用。
2. addChild(chlid)的时候
当我们使用addChild(chlid)时,首先会重新设置该组件和该组件的子孙的样式缓存,然后调用chlid.styleChanged(null) 和chlid的子孙的styleChanged(null)方法。
3, 设置 styleName
当我们给一个组件(比如实例名是child)设置styleName属性时,首先会重新设置该组件和该组件的子孙的样式缓存,然后调用chlid.styleChanged("styleName")和chlid的子孙的styleChanged("styleName")方法。
4, 运行时载入样式表单
运行时载入样式表单我们通常会使用StyleManager.loadStyleDeclarations(url:String, update:Boolean = true, trustContent:Boolean = false, applicationDomain:ApplicationDomain = null, securityDomain:SecurityDomain = null)方法。当把参数update设置为true时表示样式表单载入完成后马上更新样式。其原理是:样式表单载入完成后程序中的所有组件会重新设置组件的样式缓存,并调用组件的styleChanged(null)方法。
当我们建立一个ActionScript自定义组件(ActionScript Custom Components),并且该组件支持自定义样式的时候,我们的组件类里面必须要有一个
程序代码方法。为什么呢?应为如果没有这个方法,你怎么来检测你的样式的改变呢?
通过我上面的分析,相信你一定能设计出一个出色的适应Flex框架的支持自定义样式的组件。关于“自定义组件支持自定义样式”你可以参考Flex帮助文档里面的 ActionScript Custom Components / Custom Style Properties 一节。
此文禁止转载,但是您可以以超级链接的方式链接到这篇文章。
下面是 UIComponent 组件里面的styleChanged(styleProp:String):void方法的定义,和本文无关,只是方便我自己查阅而放在这里。
程序代码
在Flex样式工作原理分析 Part One中,我们分析了组件是如何获得样式信息的,下面来谈一下设置样式是如何工作的。
每当组件需要重新设置自己的样式时(比如说调用了setStyle()方法或者设置了styleName属性),组件的styleChanged(styleProp:String)方法就会被调用,然后我们在styleChanged(styleProp:String)方法体里面根据参数styleProp的值的不同来对组件的样式做出相应的处理。那么什么时候组件的styleChanged(styleProp:String)方法会触发呢?下面介绍如下:
1,setStyle()方法
当我们调用setStyle()方法的时候,首先会调用该组件的styleChanged(styleProp)然后判断改变的样式是否是可继承样式,如果是,则调用该组件的所有子孙的styleChanged(styleProp)方法。比如:
程序代码<mx:Canvas id="myCanvas">
<mx:Vbox id="box" x="0" y="10" width="200">
<mx:Label id="text1" text="@Resource(key='name', bundle='test')" color="#ff0000"/>
<mx:Label id="text2" text="@Resource(key='age', bundle='test')" styleName="ageLabel"/>
<mx:Label id="text3" text="@Resource(key='sex', bundle='test')"/>
<mx:Label id="text4" text="{resourceManager.getString('test', 'sex')}"/>
</mx:Vbox>
<mx:Button id="myBtn" x="27" y="100" label="change" click="changeHandler(event)"/>
</mx:Canvas>
<mx:Vbox id="box" x="0" y="10" width="200">
<mx:Label id="text1" text="@Resource(key='name', bundle='test')" color="#ff0000"/>
<mx:Label id="text2" text="@Resource(key='age', bundle='test')" styleName="ageLabel"/>
<mx:Label id="text3" text="@Resource(key='sex', bundle='test')"/>
<mx:Label id="text4" text="{resourceManager.getString('test', 'sex')}"/>
</mx:Vbox>
<mx:Button id="myBtn" x="27" y="100" label="change" click="changeHandler(event)"/>
</mx:Canvas>
当我们调用 myCanvas.setStyle("color", 0xff0000)的时候,首先会重新设置该组件的样式缓存(CSS style cache),
这样调用myCanvas.getStyle("color")时就能得到值0xff0000。然后调用myCanvas.styleChanged("color"); 因为
color是可继承样式,所以会接着调用box.styleChanged("color"),text1.styleChanged("color"),text2.styleChanged("color"),text3.styleChanged("color"),text4.styleChanged("color"),myBtn.styleChanged("color");
当我们调用 myCanvas.setStyle("backgroundColor", 0xff0000)的时候,首先调用myCanvas.styleChanged("backgroundColor")因为backgroundColor不是可继承样式,所以myCanvas的子孙的styleChanged(styleProp)方法不会被调用。
2. addChild(chlid)的时候
当我们使用addChild(chlid)时,首先会重新设置该组件和该组件的子孙的样式缓存,然后调用chlid.styleChanged(null) 和chlid的子孙的styleChanged(null)方法。
3, 设置 styleName
当我们给一个组件(比如实例名是child)设置styleName属性时,首先会重新设置该组件和该组件的子孙的样式缓存,然后调用chlid.styleChanged("styleName")和chlid的子孙的styleChanged("styleName")方法。
4, 运行时载入样式表单
运行时载入样式表单我们通常会使用StyleManager.loadStyleDeclarations(url:String, update:Boolean = true, trustContent:Boolean = false, applicationDomain:ApplicationDomain = null, securityDomain:SecurityDomain = null)方法。当把参数update设置为true时表示样式表单载入完成后马上更新样式。其原理是:样式表单载入完成后程序中的所有组件会重新设置组件的样式缓存,并调用组件的styleChanged(null)方法。
当我们建立一个ActionScript自定义组件(ActionScript Custom Components),并且该组件支持自定义样式的时候,我们的组件类里面必须要有一个
程序代码override public function styleChanged(styleProp:String):void
{
// 方法体
}
{
// 方法体
}
通过我上面的分析,相信你一定能设计出一个出色的适应Flex框架的支持自定义样式的组件。关于“自定义组件支持自定义样式”你可以参考Flex帮助文档里面的 ActionScript Custom Components / Custom Style Properties 一节。
此文禁止转载,但是您可以以超级链接的方式链接到这篇文章。
下面是 UIComponent 组件里面的styleChanged(styleProp:String):void方法的定义,和本文无关,只是方便我自己查阅而放在这里。
程序代码/**
* Detects changes to style properties. When any style property is set,
* Flex calls the <code>styleChanged()</code> method,
* passing to it the name of the style being set.
*
* <p>This is an advanced method that you might override
* when creating a subclass of UIComponent. When you create a custom component,
* you can override the <code>styleChanged()</code> method
* to check the style name passed to it, and handle the change accordingly.
* This lets you override the default behavior of an existing style,
* or add your own custom style properties.</p>
*
* <p>If you handle the style property, your override of
* the <code>styleChanged()</code> method should call the
* <code>invalidateDisplayList()</code> method to cause Flex to execute
* the component's <code>updateDisplayList()</code> method at the next screen update.</p>
*
* @param styleProp The name of the style property, or null if all styles for this
* component have changed.
*/
public function styleChanged(styleProp:String):void
{
// If font changed, then invalidateProperties so
// we can re-create the text field in commitProperties
if (this is IFontContextComponent && hasFontContextChanged())
invalidateProperties();
// Check to see if this is one of the style properties
// that is known to affect layout.
If (!styleProp ||
styleProp == "styleName" ||
StyleManager.isSizeInvalidatingStyle(styleProp))
{
// This style property change may affect the layout of this
// object. Signal the LayoutManager to re-measure the object.
invalidateSize();
}
if (!styleProp ||
styleProp == "styleName" ||
styleProp == "themeColor")
{
initThemeColor();
}
invalidateDisplayList();
if (parent is Iinvalidating)
{
if (StyleManager.isParentSizeInvalidatingStyle(styleProp))
Iinvalidating(parent).invalidateSize();
if (StyleManager.isParentDisplayListInvalidatingStyle(styleProp))
Iinvalidating(parent).invalidateDisplayList();
}
}
* Detects changes to style properties. When any style property is set,
* Flex calls the <code>styleChanged()</code> method,
* passing to it the name of the style being set.
*
* <p>This is an advanced method that you might override
* when creating a subclass of UIComponent. When you create a custom component,
* you can override the <code>styleChanged()</code> method
* to check the style name passed to it, and handle the change accordingly.
* This lets you override the default behavior of an existing style,
* or add your own custom style properties.</p>
*
* <p>If you handle the style property, your override of
* the <code>styleChanged()</code> method should call the
* <code>invalidateDisplayList()</code> method to cause Flex to execute
* the component's <code>updateDisplayList()</code> method at the next screen update.</p>
*
* @param styleProp The name of the style property, or null if all styles for this
* component have changed.
*/
public function styleChanged(styleProp:String):void
{
// If font changed, then invalidateProperties so
// we can re-create the text field in commitProperties
if (this is IFontContextComponent && hasFontContextChanged())
invalidateProperties();
// Check to see if this is one of the style properties
// that is known to affect layout.
If (!styleProp ||
styleProp == "styleName" ||
StyleManager.isSizeInvalidatingStyle(styleProp))
{
// This style property change may affect the layout of this
// object. Signal the LayoutManager to re-measure the object.
invalidateSize();
}
if (!styleProp ||
styleProp == "styleName" ||
styleProp == "themeColor")
{
initThemeColor();
}
invalidateDisplayList();
if (parent is Iinvalidating)
{
if (StyleManager.isParentSizeInvalidatingStyle(styleProp))
Iinvalidating(parent).invalidateSize();
if (StyleManager.isParentDisplayListInvalidatingStyle(styleProp))
Iinvalidating(parent).invalidateDisplayList();
}
}
评论: 0 | 引用: 0 | 查看次数: 3118
发表评论
上一篇
下一篇

文章来自:
Tags: