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();
        }
    }
    
}
posted @ 2011-04-02 10:35  as爱好者  阅读(1178)  评论(3编辑  收藏  举报