我想设计一个扩展Button的自定义组件,它将有两个新样式:selectedColor和selectedFontSize。这些将允许按钮在选择按钮时具有不同的文本标签颜色和字体大小。 (当我说'选中'时我的意思是选择状态,而不是被选中(鼠标按下)。
我采用的方法是扩展Button,添加两个新样式,然后覆盖selected
setter,然后在原始颜色样式上使用setStyle将字体颜色更改为selectedColor(如果选择了按钮) )或颜色(如果取消选择按钮)。
为了简单起见,我在本例中使用了selectedColor,但我希望能够为selectedFontSize执行此操作。
[Style(name="selectedColor",type="uint", format="Color", inherit="no")]
[Style(name="selectedFontSize",type="Number",inherit="no")]
private var _deselectedColor:uint;
private var _selectedColor:uint;
override public function set selected(value:Boolean):void {
super.selected = value;
_selectedColor = getStyle("selectedColor") as uint;
if (!_deselectedColor)
_deselectedColor = getStyle("color") as uint;
if (selected)
setStyle("color",_selectedColor);
else
setStyle("color",_deselectedColor);
}
我正在存储原始颜色(取消选择的颜色),因为它在我setStyle("color",_deselectedColor)
时被覆盖。当取消选择按钮时,我需要有一些方法来检索它。
这种方法存在许多问题。首先,第一次调用选定的setter时,在对象构造期间,尚未填充样式。所以我得到的color
为0x000000,selectedColor
为0x000000。一旦我在构造后手动更改按钮状态,样式就能正确读入,但到那时已经太晚了,我已经存储了错误的值。此外,我需要能够通过mxml,actionscript setStyle方法或通过css设置样式更新,无论是静态还是动态。这种方法显然不会这样做。
我也尝试重写setStyle
和styleChanged
方法。当通过mxml初始化按钮时,setStyle
在构造期间永远不会被调用,所以这是不行的。调用styleChanged
,但使用null作为styleProp,而不是我需要的颜色。
专业人士如何做到这一点?
答案 0 :(得分:0)
我想我现在已经有了更加优雅(并且正在工作!)的答案。
我最终在updateDisplayList()中完成了工作,因此更新将在官方更新周期中延迟,而不是在执行选定的setter时强制更新。为了确保我没有存储不正确的取消选择颜色值,我现在只在选择按钮时存储它,并在取消选择按钮时清除存储。
我也使用CSSStyleDeclaration类,正如Amarghosh建议的那样,用css和mxml来管理自定义样式的阅读。
最后,我发现的一件大事是我需要调用super.callLater(invalidateDisplayList),否则按钮只会在我滚动时更新。
发布完整的解决方案。希望这有助于其他正在钻研定制组件世界的人!
import flash.display.Graphics;
import flash.geom.Matrix;
import mx.controls.Button;
import mx.styles.CSSStyleDeclaration;
import mx.styles.StyleManager;
[Style(name="selectedColor",type="uint", format="Color", inherit="no")]
[Style(name="selectedFontSize",type="Number",inherit="no")]
public class ControlBarButton extends Button
{
private static var classConstructed:Boolean = constructStyle(); // initialize default style properties
public function ControlBarButton() {
super();
}
private static function constructStyle():Boolean {
var style:CSSStyleDeclaration = StyleManager.getStyleDeclaration( "ControlBarButton" );
// check to see if there's already an existing style declaration for this class
if (style) {
// its possible for a style to exist without defining all of the possible styles
// in which case we need to check each style explicitly and set a default if needed
if ( style.getStyle( "selectedColor" ) == undefined ) {
style.setStyle( "selectedColor", 0xFFFFFF );
}
if ( style.getStyle( "selectedFontSize" ) == undefined ) {
style.setStyle( "selectedFontSize", 12 );
}
}
else { // create a default style declaration
style = new CSSStyleDeclaration();
style.defaultFactory = function():void {
this.selectedColor = 0xFFFFFF;
this.selectedFontSize = 12;
}
StyleManager.setStyleDeclaration( "ControlBarButton", style, true );
}
return true;
}
private var selectedColorChanged:Boolean = true;
private var selectedFontSizeChanged:Boolean = true;
private var selectedChanged:Boolean = true;
override public function styleChanged(styleProp:String):void {
super.styleChanged(styleProp);
// Check to see if style changed.
if (styleProp=="selectedColor") {
selectedColorChanged=true;
invalidateDisplayList();
return;
}
if (styleProp=="selectedFontSize") {
selectedFontSizeChanged=true;
invalidateDisplayList();
return;
}
}
private var deselectedColorStored:Boolean = false;
private var deselectedColorVal:uint;
private var selectedColorVal:uint;
private var deselectedFontSizeStored:Boolean = false;
private var deselectedFontSizeVal:Number;
private var selectedFontSizeVal:Number;
override public function set selected(value:Boolean):void {
super.selected = value;
selectedChanged=true;
invalidateDisplayList();
}
override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void{
super.updateDisplayList(unscaledWidth, unscaledHeight);
// selected color
if (selectedColorChanged || selectedChanged) {
if (selected) {
if (!deselectedColorStored) {
deselectedColorVal = getStyle("color") as uint;
deselectedColorStored = true;
}
selectedColorVal = getStyle("selectedColor") as uint;
setStyle("color",selectedColorVal);
super.callLater(invalidateDisplayList);
}
else {
if (deselectedColorStored) {
setStyle("color",deselectedColorVal);
super.callLater(invalidateDisplayList);
deselectedColorStored = false;
}
}
selectedColorChanged=false;
}
// selected font size
if (selectedFontSizeChanged || selectedChanged) {
if (selected) {
if (!deselectedFontSizeStored) {
deselectedFontSizeVal = getStyle("fontSize") as Number;
deselectedFontSizeStored = true;
}
selectedFontSizeVal = getStyle("selectedFontSize") as Number;
setStyle("fontSize",selectedFontSizeVal);
super.callLater(invalidateDisplayList);
}
else {
if (deselectedFontSizeStored) {
setStyle("fontSize",deselectedFontSizeVal);
super.callLater(invalidateDisplayList);
deselectedFontSizeStored = false;
}
}
selectedFontSizeChanged=false;
}
selectedChanged=false;
}
}