让Flash自带的滚动条支持设置宽度的方法
时间:2010-08-12
来源:互联网
不可否认,程序中的Bug相当一部分系因开发人员思维不够慎密而造成的。然而,现在能使用机器语言进行编程的人可谓凤毛麟角,我们需要依赖于系统平台,编译器,甚至解释器才可以进行编程并得到成品。所有的依赖因素,都不可避免地存在漏洞,随时都有可能影响到程序员的开发进程。
AS开发也不例外,尽管FlashPlayer具有跨平台的特性,但它本身的bug,就已经让不少Aser忍无可忍,如果要结合JS,则还需要考虑浏览器的兼容问题。一个项目,时间往往要浪费在处理这些问题上,幸亏大多数客户不懂技术,看到整体进度基本过关,即使项目一拖再拖,客户也是愿意等待的。
目前我的时间相对宽松一些,故计划把以前遇到过的一些问题进行整理,然后在此处发帖,并提出解决方案以抛砖引玉。
第一帖打算先向大家汇报一个密码文本框的Bug。按常规来讲,密码字段不可以通过右键菜单及快捷键等基本方法进行复制,但Flash的密码文本却没有屏蔽掉Ctrl+C,在非密码字段粘贴一下,密码字符串便一览无余。这个Adode公司,竟连密码框最基本的安全意识都缺乏,枉他还做了几年的安全沙箱。曾计划向Adobe提交此Bug,无奈国内访问速度过慢,再者密码框查看工具也已经比较成熟,我就没再考虑提交了。
按我原来的安排,今天先把自己为修复此Bug而扩展的PasswordTextField类在本论坛公开,不过我今天很意外地发现,FlashPlayer10.1已经对此进行了修正,我的PasswordTextField也可以功成身退了。
所以,今天向各位汇报的,是另一个问题。为了让Adobe用户开发更为方便,Adobe的AS程序员为Flash及Flex都开发了一套UI组件,基本上能满足中小型Web应用程序的需求。但是,这当中包含的一些小Bug非常让AS程序员头痛,有的人为了修正它,调用组件后,写一些有针对性的函数去处理,有的人则干脆放弃自带组件,进行自主开发,或者用其他组件库如Aswing、apple等,有的则退而求其次,说服其他部门的同事,在非技术层面上采用其他方案代替。
由于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();
}
}
}
调用这些类时,必须保证库里包含了父类的组件,因为调用父类时同样需要库里存在组件的情况下才可以正常编译。
附件

2010-8-12 15:10

2010-8-12 15:10, 下载次数: 65
作者: HBrO 发布时间: 2010-08-12
我就从来不敢用组件
作者: flash023 发布时间: 2010-08-12
但当我两年前发现自己写的那套组件在FlashPlayer10下有太多的Bug以后,深受打击,就开始尝试去使用默认组件了。
作者: HBrO 发布时间: 2010-08-12
作者: flash023 发布时间: 2010-08-12

作者: HBrO 发布时间: 2010-08-12
到目前为止我所有的项目都只有两种选择:用自己的组件库,直接使用FLEX

作者: jimohuoshan 发布时间: 2010-08-14
作者: liaoruilu 发布时间: 2010-08-14
作者: xtpz 发布时间: 2010-08-14
自己写组件库是个明智的选择,但是我比以前懒了很多。
作者: HBrO 发布时间: 2010-08-17

作者: 0xFF336699 发布时间: 2011-07-19
热门阅读
-
office 2019专业增强版最新2021版激活秘钥/序列号/激活码推荐 附激活工具
阅读:74
-
如何安装mysql8.0
阅读:31
-
Word快速设置标题样式步骤详解
阅读:28
-
20+道必知必会的Vue面试题(附答案解析)
阅读:37
-
HTML如何制作表单
阅读:22
-
百词斩可以改天数吗?当然可以,4个步骤轻松修改天数!
阅读:31
-
ET文件格式和XLS格式文件之间如何转化?
阅读:24
-
react和vue的区别及优缺点是什么
阅读:121
-
支付宝人脸识别如何关闭?
阅读:21
-
腾讯微云怎么修改照片或视频备份路径?
阅读:28