About

<#TEMPLATE_INCLUDE_NINEPAGE_ABOUTME#>
  • Mar

    10

    <!--spark 版本的 DateTimeFormatter 的毫秒格式有bug,这个SSS并不会起作用--> 
    <s:DateTimeFormatter id="df" dateTimePattern="yyyy年MM月dd日kk时mm分ss秒SSS"/> 

    <!--如果使用mx 版本的 DateFormatter 的毫秒格式正格--> 
    <mx:DateFormatter id="df" formatString="YYYY年MM月DD日JJ时NN分SS秒QQQ"/>

    这个 DateTimeFormatter Bug 在 2014 年时就提交在 Adobe 社区,但过去了五年时间还是没有被修正。而引发这个 DateTimeFormatter Bug 的是 AS3 运行时环境产生的,并不是 AS代码问题。

    如果一定要使用 Spark 版本格式设置,需要使用类似 new Date().milliseconds 这样的方式,手动将毫秒添加到末尾。

    Mar

    9

    个人不喜欢渐隐渐现的效果。在以前纯 MX 开发时并不会有这样的问题产生,而在 Spark 组件或 Spark 与 MX 混合开发时就会有Bug产生, modalTransparencyDuration 直接设置为0,这个模糊效果的设置并不会起作用,需要设置一个极小值,比如0.01才会起作用。

    modalTransparencyBlur:3;
    modalTransparencyDuration:0;//这个是bug,上面的Blur模糊设置并不会起作用
    modalTransparencyDuration:0.01;//OK

    Feb

    17

    AIR SDK 22 开始,在对 AIR 桌面应用程序开发时允许加入 requestedDisplayResolution 标签,用以高清缩放显示文字。但发现一个bug,无论是在 Win10 或 MAC 系统中(一般 Win 10 小尺寸的高分屏2K会以125%或150%显示,或 Retina 屏的 MAC 电脑中)都存在,包括最新的 AIR SDK 32 版本也试了一样的结果,凡是 stage 属性的 contentsScaleFactor 如果不为1,stage 对象产生缩放效果后,虽然其它对象都是正常的,但 TextField 是个特例,它只是看起来像按 125%或 150%缩放的,但实际它并不是,它同时产生了字体大小的变化、字间距、行间距等变化,按本人的理解这种变化结果是字符最终显示以像素为单位的,所以会被四舍五入,不像矢量或位图对象宽高都可以使用浮点数。

    一般情况下使用并不会有问题,但如果此后对TextField 调用 Bitmap 的 draw() 方法(或对某个包含 TextField 对象的显示对象调用位图的 draw() 方法),产生的位图并不是与 contentsScaleFactor 缩放后的显示结果相同的,而是与 contentsScaleFactor 属于为 1 时的结果相同。当字数越多、行数越多的时候,这种差异会越明显(因为每一行的行间距、字间距等都被四舍五入)。

    能想到的方法就是使用 TLFTextField 代替 TextField ,但觉的 TLFTextField 问题也不少,比如当侦听器侦听 change 事件的时候,输入一个字符,会产生两次 change 事件。我囧!

    还有现在的 TLF 文本版本比较多,建义找个最新版本吧。查看了 Apache Flex SDK 帮助手册有 TextLayoutVersion.VERSION_3_0 版本,比现在官方的 VERSION_2_0 还要新。我在使用官方的 VERSION_2_0 又发现了Bug,如果编译器的 -swf-version 设为 23-25 正常,如果大于 25 当输入的文字超过两行时有时候会让前面的文字消失(有时需要按回车才能让它重新显示)。我试了将 SDK 换成 Apache Flex SDK 的 VERSION_3_0  最新版本,将编译器的 -swf-version 设为最新的 43 版本编译出来后的结果是正确的。

    不过使用 TLFTextField 与 TextField 有一个样式功能上缺陷,如果通过 TextFormat 设置样式时,bullet 属性是无效的。我囧囧囧!

    相关资料:《处理大小和缩放对象》中间有一段文字在加粗“注:”字后面有介绍。

    Jun

    24

    基本描述

    2K、4K 等高分辨率屏幕(也被称为“高分屏”)越来越普及,当小尺寸的高分屏出现时就需要用到缩放,一些 Adobe AIR 应用在高分屏中缩放后变模糊(不仅是旧有的 Adobe AIR 应用程序,好多原有的应用程序都出现了这种问题)。

    如:https://tracker.adobe.com/#/view/AIR-3975136

    解决方法

    升级 Adobe AIR SDK 到 22.0 以上的版本,并在应用的 -app.xml 描述文件的 initialWindow 标签内新增一个子标签:<requestedDisplayResolution>high</requestedDisplayResolution>(与 iPhone 设置 Retina 屏那个标签一样)。

    https://helpx.adobe.com/cn/flash-player/release-note/fp_22_air_22_release_notes.html

    此时 Stage.contentScaleFactor 属性就能正确反应缩放系数的值了。

    Apr

    19

    转载一个漂亮的 Flex4 Tooltips(其实我觉的它一点也不漂亮……好像就多了一个箭头么?):Flex4NiceTooltips.zip

    原文地址:http://www.hulstkamp.com/articles/flex-nicer-tooltips-and-balloon-help/srcview/index.html

    Apr

    19

    许多 Web 端与客户端程在上传文件时都会利用到 Flash AS3 技术,在 ADOBE 官方提供的《ADOBE ® ACTIONSCRIPT® 3.0 编程》手册中有一篇完整的官方示例教程:《Adobe ActionScript 3.0 示例:上载和下载文件》。

    Feb

    4

    现在的新版 本 Feathers 为了改善开发者的体验,已经大大简化了外观、子组件相关部份的 API,虽然下面的这些旧资料并不一定适用于新版本(是 Feathers 1.0 开始提供的),但很多资料信息依旧完全适用于新版本,所以一并整理下来备注了。

    首先不用说的一点就是 Feathers 强烈推荐使用主题文件,主题类可以集中设置皮肤相关的代码,便于将来的维护和更新,以及替换新的主题而不影响旧有的功能业务。主题的另外最大的好处就是能自动化给组件添加皮肤(既便是相同类型的组件提供不同的皮肤)。

    但 Feathers 也同时提供了不使用主题、或在主题文件外直接设置组件外观以及子组件的 API。关于新版本的皮肤备注资料,已在博客中单独提供了备注。下面也整理了旧版的 Feathers 资料中一些通用的与皮肤外观、子组件相关的资料。

    子组件工厂:

    子组件可以通过一个“工厂”设置皮肤,这里的“工厂”只是一种设计模式的叫法,跟其它什么“事件侦听器”、“样式提供程序”一样,其实就是个普通的函数在不同情况下叫法不一样。当一个组件需要子组件时调用这个函数,但这个函数不接受参数,却会返回一个子组件对象。下面看个工厂的例子,就是生成 Slider 组件的 thumb 子组件工厂:

    slider.thumbFactory = function():Button
    {
        var thumb:Button = new Button();
        thumb.defaultSkin = new Scale9Image( upTextures );
        thumb.downSkin = new Scale9Image( downTextures );
        return thumb;
    };

    如上代码中,函数创建了一个 Button 实例,在返回之前给它添加了一些皮肤。

    子组件的子组件:

    有些子组件会复杂一些,自身也会带有一些子组件,则可以为这些子组件单独提供工厂函数,以引用的方式一层一层的传递工厂函数。如下代码,给一个 List 组件设置滚动条的皮肤:

    function simpleScrollBarThumbFactory():Button
    {
        var thumb:Button = new Button();
        thumb.defaultSkin = new Scale3Image( thumbTextures );
        return thumb;
    }

    function simpleScrollBarFactory():SimpleScrollBar
    {
        var scrollBar:SimpleScrollBar = new SimpleScrollBar();
        scrollBar.thumbFactory = simpleScrollBarThumbFactory;
        return scrollBar;
    }

    list.verticalScrollBarFactory = simpleScrollBarFactory;

    如上代码,其实也可以将 simpleScrollBarThumbFactory() 函数以嵌套函数的方式放在 simpleScrollBarFactory() 函数内,但子组件过多时可能会不方便阅读代码。

    重复使用(并联)的工厂:

    如果组件已经设置了外观,并且想要继续对它的子组件进行其它属性设置,可以重复使用工厂,如下代码,已经在一个工厂方法中设置了 Panel 的 header 的外观,但还想进一步设置或修改它的 title 属性:

    var headerWithSkinsFactory:Function = panel.headerFactory;
    panel.headerFactory = function():Button
    {
        var header:Header = headerWithSkinsFactory();
        header.title = "Tools";
        return header;
    };

    开发者虽然可以在一个工厂中设置所有的外观以及所有的属性,但有时候仅仅只是想要在后期动态的修改它的 title 属性,这种方法就必不可少了。

    子组件属性:

    开发者也可以不使用工厂,而是通过父组件的“子组件属性”来“引用”子对象设置属性,所有设置的值会在下一次渲染时生效。这种方式性能略差一点,大多数情况下推荐使用工厂方法。但这种方式适用于在创建子组件后很久才调整属性和皮肤。以上面的 slider 为例:

    slider.thumbProperties.defaultSkin = new Scale9Image( upTextures );
    slider.thumbProperties.downSkin = new Scale9Image( downTextures );

    如上代码通过 thumbProperties 属性设置的皮肤,并不会立即将设置传递给子组件,而是要等到下一帧的渲染时才会传递给子组件。一般来说开发者不能通过这种方式去获取子对象的属性值,只应该使用这种方式来设置属性的值。thumbProperties 对象并不知道它存储数据的实际 Button 实例的任何内容。所以以下代码将产生错误,除非开发者自己实际设置了 isSelected:

    var isSelected:Boolean = slider.thumbProperties.isSelected;

    这段话的主要意思就是指 “thumbProperties ”只是一个存储数据的对象,这个子组件属性并不是真正的引用到了子组件,而只是给出了用于下一次渲染时提供给 thumb 按钮需要的数据,所以 thumbProperties 本身并不是 thumb 子组件。所以上面的黄色字“子组件属性”与“引用”打了引号,只是看起来好像是子组件的引用,但实际上只是给子组件提供需要的属性数据(由于在下一帧渲染时需要传递给某个子组件,所以对应的子组件是需要被先创建好的)。

    嵌套的子组件属性:

    如上面的 slider 的 thumbProperties “伪引用”了子组件,这种伪引用可以嵌套的,听起来好凌乱(- -!),所以一般都推荐使用工厂方法,但如果有需要的话也可以作为一种可选的方法用于实际开发。

    再次以 list 组件的滚动条为例,但这次不使用工厂,而是使用嵌套的“子组件属性”:

    list.verticalScrollBarProperties.@thumbProperties.defaultSkin = new Scale3Image( thumbTextures );

    注意在这里使用了属性运算符(@)。属性运算符告诉系统在另一个“子组件属性”对象内创建“子组件属性”对象,但前提是它尚不存在。 它不能用于常规属性,所以这就是为什么 defaultSkin 不以@开头。

    但使用这种语法有一个好处,可以避免覆盖可能已经存在的对象。如果使用一个全新的对象设置 thumbProperties,如下面这样的代码,它将替换整个应用程序中全部的 thumbProperties:

    //警告:这可能会覆盖的东西!
    list.verticalScrollBarProperties.thumbProperties =
    {
       defaultSkin: new Scale3Image( thumbTextures )
    };

    在这里就可以使用 @thumbProperties 并单独传递属性,以便不会删除 thumbProperties 中已经存在的任何内容(这样就避免了替换整个对象,只是单个属性的替换)。

    Feb

    4

    3.0 版本的项目升级到 3.1 的版本时,项目本身不需要进行修改(只是一个次要版本的升级)。但有一些简化的 API,提高开发人员的体验,特别是在处理字体样式和皮肤方面。

    用 starling.text.TextFormat 设置字体样式:

    从 Starling 2.0 开始,引入了 starling.text.TextFormat 类,它定义了所有类型文本使用的常见字体样式,包括位图字体和TTF / OTF字体。以前,要在 Feathers 文本渲染器上使用自定义字体样式,需要使用不同的类并设置不同的属性,具体取决于使用的文本渲染器。例如,TextBlockTextRenderer 具有类型为flash.text.engine.ElementFormat 的 elementFormat 属性,而 TextFieldTextRenderer 具有类型为 flash.text.TextFormat 的 textFormat 属性。现在,所有文本渲染器都有统一的方式来支持 starling.text.TextFormat 类。

    事实上,现在的字体样式不需要直接设置在文本渲染器对象本身上,开发者可以直接在使用到文本组件的对象上直接设置就可以,比如 Label、Button 这些组件用到了文本渲染器,就可以直接对这些父组件设置字体样式,父组件会自动将设置好的字体样式传递给文本渲染器。以 Label 组件为例:

    var label:Label = new Label();
    label.text = "Hello World";
    label.fontStyles = new TextFormat( "_sans"20, 0xff0000 );
    this.addChild( label );

    就是如此简单。在绝大多数情况下,根本不需要通过文本渲染器工厂(text renderer factories)设置。

    如果想设置 Label 禁用时的字体样式,只需如下代码:

    label.disabledFontStyles = new TextFormat( "_sans"20, 0x999999 );

    现在含有文本渲染器的绝大多数组件都包含了 fontStyles、disabledFontStyles 属性。如果一个组件是可选择的(类似“开关”),也会包含 selectedFontStyles 属性。

    如果组件包含有更多的状态,如 Button 组件,还包含了 setFontStylesForState() 方法用于设置不同状态字体的样式,此方法可以传入一个状态名称和一个用于设置字体样式的 TextFormat  对象,如下代码可以设置更多的状态时字体样式:

    var button:Button = new Button();
    button.setFontStylesForState( ButtonState.DOWN, new TextFormat( "_sans"20, 0xffffff ) );
    button.setFontStylesForState( ButtonState.HOVER, new TextFormat( "_sans"20, 0xff9999 ) );

    样式属性与主题:

    在以前的 Feathers 版本中,单独的皮肤设置经常会与主题文件中的代码产生“冲突”。为了避免这种问题,过去可能需要通过使用 AddOnFunctionStyleProvider 类,设置组件的 styleProvider 属性为 null,等待组件的初始化,或者需要扩展主题,但有时候可能仅仅只是需要一些微小的调整,所以这些方法无论是哪一种,都会显示麻烦一点。

    从 Feathers 3.1 开始, 一些属性现在被定义为“样式属性”。如果在主题之外设置样式属性,不需要再担心会被主题替换掉,而且还会同时保留主题文件中其它的皮肤设置(其它样式不会受到影响)。例如,如果在自定义的主题文件之外设置按钮的字体样式,但保持主题的背景皮肤,可以很容易:

    var button:Button = new Button();
    button.label = "Click Me";
    //不会再被主题文件中替换
    button.fontStyles = new TextFormat( "_sans"20, 0xff0000 );
    this.addChild( button );

    如果想要知道 Button 类被单独分离出来的样式属性有哪些,可以查看 API 手册

    主题中的最小尺寸:

    如果在主题文件中设置了普通属性,那么依旧有可能与主题外的代码产生“冲突”。例如,不应该直接对主题中的组件本身设置 minWidth 和 minHeight 属性。这些属性不被视为“样式属性”,所以如果在主题外同时设置的话,就会产生冲突。

    //比如在主题内有如下代码
    private function setButtonStyles( button:Button ):void
    {
        button.defaultSkin = new ImageSkin( texture );
        button.minWidth = 40//在主题内最好不要对组件本身设置这种普通属性
    }

    取而代之的是应该设置组件的皮肤:

    //在主题内
    private function setButtonStyles( button:Button ):void
    {
        var skin:ImageSkin = new ImageSkin( texture );
        skin.minWidth = 40;//对组件的皮肤进行设置
        skin.minHeight = 20;
        button.defaultSkin = backgroundSkin;
    }

    如果组件没有显示的尺寸设置,组件就会用皮肤的尺寸用于测量步骤。所以如上代码在皮肤上设置尺寸,实际上跟在组件上设置尺寸基本上是一样的。

    如果有些组件不需要显示皮肤,可以使用一个全透明的背景皮肤,可以简单地传入一个starling.display.Quad,设 alpha 属性设置为 0:

    var backgroundSkin:Quad = new Quad( 4020 );
    backgroundSkin.alpha = 0;
    component.backgroundSkin = backgroundSkin;

    Starling 不会要求 GPU 渲染一个完全透明的显示对象,因此这个透明背景不会增加 GPU 绘制调用的次数,也不会影响 GPU 绘制的性能。但这个 Quad 的尺寸会被视为测量步骤中的最小尺寸。

    当一个显示对象没有 minWidth 与 minHeight 属性时(如上面的 Quad),它的普通 width 与 height 属性也会被当作最小值。如果一定需要有 minWidth 与 minHeight 的值比普通的 width 与 height 属性值还要小,可以考虑使用 ImageSkin。

    Feb

    3

    升级指南:重复的常量移动到共享类:

    在以往旧的 Feathers 版本中,存在大量的重复常量。例如,可以在Button、DefaultListItemRenderer、HorizontalLayout 和 TiledRowsLayout 类(以及其他地方)上找到 HORIZONTAL_ALIGN_LEFT。在 Feathers 3.0 中,现在可以使用一个共享的 HorizontalAlign.LEFT 常量,换句话说,只要在一个类中使用了 HorizontalAlign.LEFT 常量,在后续其它的类中如果也同样需要这个常量就可以很容易找到它了。

    其它一些重复的常量也差不多都被合并处理了。以下这些类具有共享常量:

    feathers.controls.AutoSizeMode
    feathers.controls.ButtonState
    feathers.controls.DecelerationRate
    feathers.controls.ScrollBarDisplayMode
    feathers.controls.ScrollInteractionMode
    feathers.controls.ScrollPolicy
    feathers.controls.TextInputState
    feathers.layout.Direction
    feathers.layout.HorizontalAlign
    feathers.layout.RelativePosition
    feathers.layout.VerticalAlign

    有关弃用的常量对应到新的共享常量的详细信息,请参阅《附录:已弃用的API列表》。

    使用原先重复的常量不再被推荐的,虽然在短时间内为了兼容性还可以继续使用,但将来某些个版本中是一定会被删除的。如果旧项目中大量的用到了这些常量,需要快速的替换升级,可以参考《附录:查找和替换正则表达式》。

    Feb

    3

    升级指南:使用 Feathers 组件进行多分辨率开发:

    Feathers 3.0 完全支持 Starling 多分辨率开发中描述的 Starling 的 contentScaleFactor 系统。Feathers 甚至还提供了一些技巧,使其很容易扩展到任何移动设备的屏幕,同时保持其原生长宽比。

    屏幕像素密度缩放因子管理器(ScreenDensityScaleFactorManager):

    ScreenDensityScaleFactorManager 类提供了一种方便的方式,用来自动计算恰当的 contentScaleFactor 值,同时保持移动设备屏幕的宽高比(这是受到 Android 系统的启发,同时考虑了屏幕的像素密度和分辨率尺寸)。

    下面的代码演示了 ScreenDensityScaleFactorManager 的使用方法:

    public class Startup extends Sprite
    {
        private var mStarling:Starling;
        private var mScaler:ScreenDensityScaleFactorManager;

        public function Startup()
        {
            mStarling = new Starling( Game, stage );
            mScaler = new ScreenDensityScaleFactorManager( mStarling );
            mStarling.start();
        }
    }

    开发者不需要设置 Starling 的 viewPort,也不需要设置 Starling 舞台的 stageHeight 与 stageWidth 属性。ScreenDensityScaleFactorManager 类会自动为开发者处理这些(既使设备旋转了方向)。

    在使用 Feathers 库进行开发的时候,ScreenDensityScaleFactorManager 的使用是可选的。如果想按 Starling WIKI 手册中 《Multi-Resolution Development》介绍的那样手动设置 viewPort 与  舞台的 stageHeight 与 stageWidth 属性也同样可以。

    示例主题的变化:

    Feathers UI 库提供的示例主题已被修改成为允许 Starling 通过 contentScaleFactor 自动缩放资源,在示例主题中的缩放因子为 2。示例主题的缩放因子不再是通过屏幕像素密度计算出来的,无论是像素尺寸或字体大小,都使用相同的缩放因子。

    如果示例主题的子类定义了一个 scale9Grid 矩形,值可能需要经过缩放计算才能适合在 Feathers 3.0 中使用。在以前的 Feathers 版本中,示例主题的纹理缩放因子都是 1,然后手动计算需要缩放的倍数。由于现在的缩放因子变成了2,因为旧的 scale9Grid 相关的值应该除以2。需要注意的是,如果原先是个奇,向上取整,皮肤 可能需要扩展额外的像素以取得偶数值。