uiscrollbar 的重写,改变uiscrollbar样式
由于Adobe的组件开源,我们还可以通过直接修改代码,重新编译。但我在使用FlashCS5的过程中,修改组件代码,重新编译,组件并没有发生任何变化,在ComponentShim里编译swc,也得不到我修改后的结果,将这个类库的目录添加到项目的源路径也一样不奏效,最后尝试反编译来修改,结果报出一堆错误。
无奈之下,我只能选择扩展原有类,通过重写某些方法来修复这些带Bug的组件。
Flash/Flex自带的UIScrollBar不支持纵滚动条宽度和横滚动条高度的设置,把设置尺寸和修改样式的函数通通试了一遍,没有一个可以达到目的。即使用Embed标签嵌入尺寸不等于默认值的图片,发布后,组件也会自动将图片调整为默认尺寸。
查看ScrollBar(UIScrollBar的父类)类的源代码,发现有以下几处代码写得很死:
复制内容到剪贴板
代码:
public static const WIDTH:Number = 15;
滚动条宽度写死在了一个常数上,因此无法在运行时进行设置。下面我们再来观察绘制组件的相关代码:
复制内容到剪贴板
代码:
/**
* @private (protected)
*
* @langversion 3.0
* @playerversion Flash 9.0.28.0
*/
override protected function configUI():void {
super.configUI();
track = new BaseButton();
track.move(0,14);
track.useHandCursor = false;
track.autoRepeat = true;
track.focusEnabled = false;
addChild(track);
thumb = new LabelButton();
thumb.label = "";
thumb.setSize(WIDTH,15);
thumb.move(0,15);
thumb.focusEnabled = false;
addChild(thumb);
downArrow = new BaseButton();
downArrow.setSize(WIDTH,14);
downArrow.autoRepeat = true;
downArrow.focusEnabled = false;
addChild(downArrow);
upArrow = new BaseButton();
upArrow.setSize(WIDTH,14);
upArrow.move(0,0);
upArrow.autoRepeat = true;
upArrow.focusEnabled = false;
addChild(upArrow);
upArrow.addEventListener(ComponentEvent.BUTTON_DOWN,scrollPressHandler,false,0,true);
downArrow.addEventListener(ComponentEvent.BUTTON_DOWN,scrollPressHandler,false,0,true);
track.addEventListener(ComponentEvent.BUTTON_DOWN,scrollPressHandler,false,0,true);
thumb.addEventListener(MouseEvent.MOUSE_DOWN,thumbPressHandler,false,0,true);
enabled = false;
}
至此真相水落石出,轨道,按钮的尺寸全部写死在一个常数上。
与此同时,draw方法也没有调用过setSize函数所设定的width属性,整个重绘跟width属性无关(对纵滚动条而言)
复制内容到剪贴板
代码:
/**
* @private (protected)
*
* @langversion 3.0
* @playerversion Flash 9.0.28.0
*/
override protected function draw():void {
if (isInvalid(InvalidationType.SIZE)) {
var h:Number = super.height;
downArrow.move(0, Math.max(upArrow.height, h-downArrow.height));
track.setSize(WIDTH, Math.max(0, h-(downArrow.height + upArrow.height)));
updateThumb();
}
if (isInvalid(InvalidationType.STYLES,InvalidationType.STATE)) {
setStyles();
}
// Call drawNow on nested components to get around problems with nested render events:
downArrow.drawNow();
upArrow.drawNow();
track.drawNow();
thumb.drawNow();
validate();
}
所以,要让组件支持滚动条宽度设置,必须重写这两个函数。
在我的源码里,几乎没有调用过super,因为常数写得过于分散,直接调用超类函数再添加自己的修正代码也特别麻烦。
由于BaseScrollPane(及其子类),TextArea等类均应用了滚动条,所以若要让那些组件的滚动条支持宽度设置,同样需要重写相应的重绘方法,同时把ScrollBar或者UIScrollBar组件换成你扩展过的。
下面是我扩展过的ScrollBar代码:
复制内容到剪贴板
代码:
package com.hbro.controls {
import fl.controls.ScrollBar;
import fl.core.InvalidationType;
public class ResizableScrollBar extends ScrollBar{
public function ResizableScrollBar() {
// constructor code
super();
}
override protected function draw():void {
//代码从ScrollBar类拷贝过来,将常数换成与width有关的变量,以使得在调用setSize或者设置width的时候,可以改变宽度
if (isInvalid(InvalidationType.SIZE)) {
var h:Number = super.height;
//滚动条按钮按宽度进行设置,源程序写死了一个常数,导致该大小无法改变,有兴趣的朋友可以在此基础上进行修改,让按钮区域可以不呈现为正方形。
downArrow.setSize(_width,_width);
upArrow.setSize(_width,_width);
downArrow.move(0, Math.max(upArrow.height, h-downArrow.height));
//轨道宽度也要进行设置
track.move(0,_width);
track.setSize(_width, Math.max(0, h-(downArrow.height + upArrow.height)));
thumb.setSize(_width,thumb.height);
updateThumb();
}
if (isInvalid(InvalidationType.STYLES,InvalidationType.STATE)) {
setStyles();
}
// Call drawNow on nested components to get around problems with nested render events:
downArrow.drawNow();
upArrow.drawNow();
track.drawNow();
thumb.drawNow();
validate();
}
}
}
无奈之下,我只能选择扩展原有类,通过重写某些方法来修复这些带Bug的组件。
Flash/Flex自带的UIScrollBar不支持纵滚动条宽度和横滚动条高度的设置,把设置尺寸和修改样式的函数通通试了一遍,没有一个可以达到目的。即使用Embed标签嵌入尺寸不等于默认值的图片,发布后,组件也会自动将图片调整为默认尺寸。
查看ScrollBar(UIScrollBar的父类)类的源代码,发现有以下几处代码写得很死:
复制内容到剪贴板
代码:
public static const WIDTH:Number = 15;
滚动条宽度写死在了一个常数上,因此无法在运行时进行设置。下面我们再来观察绘制组件的相关代码:
复制内容到剪贴板
代码:
/**
* @private (protected)
*
* @langversion 3.0
* @playerversion Flash 9.0.28.0
*/
override protected function configUI():void {
super.configUI();
track = new BaseButton();
track.move(0,14);
track.useHandCursor = false;
track.autoRepeat = true;
track.focusEnabled = false;
addChild(track);
thumb = new LabelButton();
thumb.label = "";
thumb.setSize(WIDTH,15);
thumb.move(0,15);
thumb.focusEnabled = false;
addChild(thumb);
downArrow = new BaseButton();
downArrow.setSize(WIDTH,14);
downArrow.autoRepeat = true;
downArrow.focusEnabled = false;
addChild(downArrow);
upArrow = new BaseButton();
upArrow.setSize(WIDTH,14);
upArrow.move(0,0);
upArrow.autoRepeat = true;
upArrow.focusEnabled = false;
addChild(upArrow);
upArrow.addEventListener(ComponentEvent.BUTTON_DOWN,scrollPressHandler,false,0,true);
downArrow.addEventListener(ComponentEvent.BUTTON_DOWN,scrollPressHandler,false,0,true);
track.addEventListener(ComponentEvent.BUTTON_DOWN,scrollPressHandler,false,0,true);
thumb.addEventListener(MouseEvent.MOUSE_DOWN,thumbPressHandler,false,0,true);
enabled = false;
}
至此真相水落石出,轨道,按钮的尺寸全部写死在一个常数上。
与此同时,draw方法也没有调用过setSize函数所设定的width属性,整个重绘跟width属性无关(对纵滚动条而言)
复制内容到剪贴板
代码:
/**
* @private (protected)
*
* @langversion 3.0
* @playerversion Flash 9.0.28.0
*/
override protected function draw():void {
if (isInvalid(InvalidationType.SIZE)) {
var h:Number = super.height;
downArrow.move(0, Math.max(upArrow.height, h-downArrow.height));
track.setSize(WIDTH, Math.max(0, h-(downArrow.height + upArrow.height)));
updateThumb();
}
if (isInvalid(InvalidationType.STYLES,InvalidationType.STATE)) {
setStyles();
}
// Call drawNow on nested components to get around problems with nested render events:
downArrow.drawNow();
upArrow.drawNow();
track.drawNow();
thumb.drawNow();
validate();
}
所以,要让组件支持滚动条宽度设置,必须重写这两个函数。
在我的源码里,几乎没有调用过super,因为常数写得过于分散,直接调用超类函数再添加自己的修正代码也特别麻烦。
由于BaseScrollPane(及其子类),TextArea等类均应用了滚动条,所以若要让那些组件的滚动条支持宽度设置,同样需要重写相应的重绘方法,同时把ScrollBar或者UIScrollBar组件换成你扩展过的。
下面是我扩展过的ScrollBar代码:
复制内容到剪贴板
代码:
package com.hbro.controls {
import fl.controls.ScrollBar;
import fl.core.InvalidationType;
public class ResizableScrollBar extends ScrollBar{
public function ResizableScrollBar() {
// constructor code
super();
}
override protected function draw():void {
//代码从ScrollBar类拷贝过来,将常数换成与width有关的变量,以使得在调用setSize或者设置width的时候,可以改变宽度
if (isInvalid(InvalidationType.SIZE)) {
var h:Number = super.height;
//滚动条按钮按宽度进行设置,源程序写死了一个常数,导致该大小无法改变,有兴趣的朋友可以在此基础上进行修改,让按钮区域可以不呈现为正方形。
downArrow.setSize(_width,_width);
upArrow.setSize(_width,_width);
downArrow.move(0, Math.max(upArrow.height, h-downArrow.height));
//轨道宽度也要进行设置
track.move(0,_width);
track.setSize(_width, Math.max(0, h-(downArrow.height + upArrow.height)));
thumb.setSize(_width,thumb.height);
updateThumb();
}
if (isInvalid(InvalidationType.STYLES,InvalidationType.STATE)) {
setStyles();
}
// Call drawNow on nested components to get around problems with nested render events:
downArrow.drawNow();
upArrow.drawNow();
track.drawNow();
thumb.drawNow();
validate();
}
}
}