Freewind @ Thoughtworks scala java javascript dart 工具 编程实践 月结 math python english [comments admin] [feed]

(2012-07-28) Flex入门体验

广告: 云梯:翻墙vpn (省10元) 土行孙:科研用户翻墙http proxy (有优惠)

在铁哥的指引下,这几天我学习了Flex,在这里记录下这几天的入门体验,希望对Flex新手们有所帮助。由于是刚刚接触,某些地方理解可能不对,欢迎指正。

在学习过程中,我发现对一个初学某种技术的新手来说,背景知识远比技术点的讲解更加重要。比如“为什么会有这个东西,那个东西有什么用,能做什么不能做什么,什么时候该用什么”,此类问题的讲述会帮助初学者在脑海中勾勒出新技术的全景,不易迷失于细节之中。

Flex简述

在说Flex前,首先说下Flash。我在大学时曾学过flash,做过一些简单的动画,后来就放下了,所以对于它的印象一直都是“做动画广告的小工具”。实际上经过这十来年的发展,Flash已经成为了一个和Jvm、.net类似的软件开发平台,它的功能已经相当强大,既可以开发应用程序,又可以做出复杂的游戏(比如一些大型网页游戏),拥有很高的开发效率和不错的性能。相信你的电脑经常会弹出“Flash升级”的提示吧?这是Flash在不断发展的信号。Flash与Jvm、.net相比在某些方面具有较大的优势,这里不详述,具体参见铁哥的《Flash: 涅磐与重生》。

Flex是Adobe推出的一个富客户端开发框架,核心是利用Mxml+ActionScript+Css快速开发出运行于Flash平台的应用程序。发布时既可以打包为swf格式,通过flash player运行于浏览器中;又可以打包为air格式,以桌面程序方式运行于air虚拟机中。Flex是开源的,由Apache管理。

Flex的开发方式与网页开发非常相似,Mxml对应HTML,ActionScript对应JavaScript,Css还是那个Css(子集加修改)。我相信每一个开发过网站的人,都能非常容易地掌握Flex,并且(很可能)喜欢上它。

对于Flex与Html5之争,这里不多说。我相信如果你使用过Flex和Html+Js框架开发过相似的程序,你一定会喜欢上Flex。我想起我前段时间学习的一个叫Angular的前端Js框架。这个由google推出,以提供双向绑定、自定义html标签和行为来扩展html功能为卖点的Js框架,深深打动了我。我觉得它是目前所有Js前端框架中最具创意、设计最好的(没有之一)。但在看了Flex的示例代码之后,我惊奇地发现它们两者如此相似,思路几乎完全相同。只是Flex在几年前就已经实现了,而angularjs直到最近才推出1.0版(当然,Angularjs出现晚的原因在于Js语言以及多浏览器支持,大大增加了实现难度)。

我发现Flex内置了很多控件。布局、表单、标签页、菜单、树、图表等等,应有尽有。使用它们开发一些管理后台,是非常容易的事情。说到这里,我觉得Flex一个很好的方向,就是代替ExtJS来做企业信息管理系统。有很多公司采用ExtJS这种Js UI框架,个人认为这是自虐找抽的做法。我曾经在某公司做过一个ExtJs的项目,ExtJs的开发难度、调试,以及对不同浏览器的兼容,让我们整个小组都苦不堪言。由于整个产品线全部采用ExtJs开发,所以加班是整个开发部门每人每日必备。现在想来,如果公司使用的是Flex,大家都可以活得轻松很多。

另外,由于Flash在图像处理方面具有一定的优势,甚至支持3D动画,所以使用Flex可以开发出一些功能比较强大的、与图像处理相关的程序。

Flex开发工具

Flex SDK是免费的,但Adobe提供的开发工具Flex Builder是收费的。Flex Builder后来改为Flash Builder,当前版本为4.6。它基于eclipse开发,提供了很好的代码提示、错误检查、调试重构、页面设计等功能,十分好用。如果你不想用破解,还有其它工具可用,如完全免费开源的FlashDevelop,甚至使用普通的文本编辑器都可以(因为mxml/ActionScript/Css都是文本格式)。当然作为初学者,建议使用Flex Builder,至少在试用期内可以帮助你掌握Flex。

还有另一个叫Flex Catalyst的工具,也可以辅助Flex程序的开发,它的强项在于可视化。比如设计组件的外观、动画效果等,十分方便。但是该工具在今年4月停止开发,并入了Adobe Creative Suite 6 Master Collection这一软件套件中。这个套件出奇的庞大,里面包含了十几个软件,我也不清楚到底是哪个,猜测应该是合并到Flash Professional CS6中了。我想对于普通的富客户端程序开发,Flash Builder应该就够用了。

Flex中的两套UI库

Flex本身提供了两套UI库,一种是Flex3的mx库,一种是Flex4中的Spark库。这两套库是平行的,控件都很丰富,之所以要推Spark,是为了提供更好的换肤功能。因为在之前的mx库中,要修改一个组件的外观比较麻烦,只能通过CSS一点点修改,或者扩展源代码。而在Spark中,提出了“皮肤”的概念,可以在另一个mxml文件中,对某一个组件的外观进行全方位的定制。这样就可以利用其它的设计工具以可视化方式定义外观,或者直接采用第三方提供的皮肤库。

这两套库可以只用其中一个,也可以两者混用。而且两者的控件都很丰富,对于新项目而言,采用Spark比较好,因为它既支持换肤,又专门针对移动平台开发了很多控件,未来adobe也会继续开发该库。据说mx中有少量控件还没有在Spark中实现,所以在极少数情况下,你需要用到mx库。

由于这两套库的体积都比较大,对于开发一些简单的互联网上使用的组件,不太方便。比如你使用mx创建了一个最简单的项目,生成的swf文件也在200K以上。这对于国内的网速来说,还是很难接受的。所以有时候需要用到第三方小巧的UI库,比如铁哥的RedCoral(参考了minimalcomps),做简单的功能时,输出的swf文件只有几K。

学习资料

一个软件

image

几本书

几个视频

一些网址

源代码

QQ群:

Flex的重点

两个关键点

  1. 事件 事件的理解和处理非常重要,因为Flex是以事件驱动的,控件之间的交互都是通过事件触发。事件在Flex中无处不在,一定要掌握。可参考前面提到的书,以及《走在网页游戏开发的路上》相关章节。2. 绑定 绑定是Flex中一个相当有用的功能。通过把某些属性设为Bindable,可以mxml(相当于视图)中引用它们。当这些属性的值变化了,视图也会自动更新。以前这些更新都是要在as类中手写的,现在在mxml中使用该特性,让我们的代码大大简化。在Flex4中,还增加了双向绑定:视图上的修改(比如在文本框中输入了内容)会自动更新相应的属性。

其它需要注意的

  1. this ActionScript中的this跟Java相似,跟js不同。在mxml文件中引用的this,都指向mxml的root,而不是某节点。所以要想对某个控件操作,只能使用event的currentTarget/target来取得引用。ActionScript中的this,都指向所在对象。参考How to understand “this” keyword in flex2. 线程 Flash底层是多线程的,但我们的代码运行于单线程环境中,这点跟Nodejs的线程模型比较像(但因为没有深入Flex,不是很确定)。可参考:Threads in Flash and Flex,以及Threads in Actionscript 3。所以我们在处理比较繁重的计算任务时,要想办法把它们分块,以防止阻塞UI。另外,这里有个小提示:Update: As the commenter ardnarf1 points out, flash player 10 supports pixel bender kernels (programs) that can run as a filter, blend mode or a background job. A pixel bender kernel running as a background job (ShaderJob) runs on a true thread (rather than a PseudoThread) and is therefore faster. The only disadvantage here is that your background job must be programmable in pixel bender's language, Hydra.3. Event.ENTER_FRAME 在铁哥的RedCoral代中,经常会用到该事件,比如“addEventListener(Event.ENTER_FRAME, onInvalidate);”ENTER_FRAME应该是Flash动画中的一个概念,表示新的一帧到来了,为什么Flex也会用到它?Flex的默认帧频是24/秒(可设置),使用ENTER_FRAME事件,可以定时自动执行一些操作,如更新画面内容等(可参考flex的enter_frame事件详解)。需要注意的是,在某些时候,帧频会瞬间到达1000(为了快速渲染某些内部组件,不是Bug),使用时需注意。另外,如果想执行一个定时任务,可使用Timer类,timer类的执行不会引发重绘

关于Mxml

Mxml是Flex中非常有创意的地方,使用与HTML类似的方式,来声明各种可视化与非可视化组件。比如下面这段代码:


<s:Application xmlns:fx=“http://ns.adobe.com/mxml/2009”

           xmlns:s="library://ns.adobe.com/flex/spark"       
           xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600">       
<s:HGroup>       
    <s:Label text="Hello, " />       
    <s:TextInput />       
    <s:Button label="Go!" />       
</s:HGroup>       

它声明了一个Label,一个输入框和一个按钮。运行它可在浏览器中看到如下效果:

image

跟HTML是不是非常相似?

上面的HGroup、Label、TextInput、Button实际上都是spark库中的几个类。在mxml文件中以标签方式声明它们,和使用ActionScript代码创建它们,效果是相似的,只是标签方式更清晰易懂。如果我们定义了一个继承于flash.display.Sprite的类(或者创建了一个mxml文件),则可以直接在mxml中以同样方式使用它。

把mxml想像成可自行扩展的HTML,一切就明白了。

Flash Builder对mxml提供了非常好的支持,如代码提示、查错等。

关于ActionScript

ActionScript是flash中使用的编程语言。它的前几版像JavaScript,但在ActionScript 3中,增加了面向对象、静态类型等,跟Java、C#等语言非常相似。相信一个Java/C#开发者,可快速掌握。由于在ActionScript中,function是一等公民,所以有时候要比Java方便很多。

ActionScript既可嵌入到mxml中,又可放在一个单独的.as文件中。

ActionScript在语法层面支持XML,并且由于mxml本身也是xml,所以在Flex程序中,前后台的交互使用XML更多一些,也相当方便。而在JavaScript中,Json是主流。

ActionScript中即有静态类型,又有动态类型,既可使用编译器的检查功能,又能灵活处理一些动态数据,很好。

Flash Builder对ActionScript(以及mxml)都可检查错误、代码提示,还可重构,与Js相比,实在是幸福太多了。

关于CSS

Flex支持CSS的子集,另外增加了一些自己特有的东西。使用方法与普通CSS相似,这里就不多说了。

关于换肤

Spark一大特点是换肤,即在一个mxml中,定义某组件的外观。这种“定义”,不像是CSS那样小打小闹,而是脱胎换骨。先看看一些效果(来自http://www.scalenine.com):

image

image

image

可以看出,spark能做出很多不同风格的漂亮皮肤出来。

在看到皮肤文件时,我理解不了这皮肤到底是怎么定义的。皮肤文件是mxml文件,只是内容看起来很怪,有很多描述效果的标签,像是有很多层,但是,它们与组件之间到底有什么关系?!后来看了一些资料并提问,终于理解了:

原来是这样:设计spark的组件,就像是用photoshop来设计,用到了层的概念。对于某一个组件,我可以使用很多层,每个层画上不同的内容,共同组成最终的效果。而每一个组件,都以属性的方式,将一些小部件开放给皮肤文件。在皮肤文件中,可以将某个效果的id属性指向它,就把该效果用到了它身上。由于这种灵活性,可以轻易实现出很炫很复杂的效果。需要注意的是,由于层有上下,上面的会挡住下面的,所以层的顺序很重要。在皮肤mxml文件中,前面的效果在底层,下面的效果会挡住前面的,这个顺序要记住。

要实现复杂的效果,靠手写皮肤是一件非常痛苦的事情,这时可利用Flex catalyst(现在可能叫Flash CS)进行可视化设计,然后导出到Flash Builder中使用。Adobe的各软件之间的互通做得非常好,可充分利用每个软件的长处(所以要买更多的软件:)

关于states

Flex中,states是一个重要的概念。在mxml,states表示当前页面的多个不同状态。

比如用户点了“登录”按钮,上面显示了几个输入框,再点“注册”按钮,又会显示一些不同的输入框。页面还是那个页面,但上面的元素变了。在html网站中,我们有两种方式来实现。一是制作多个不同的页面,点击后跳转,二是使用js来增删改某些元素。在mxml中,采用的是后一种方式。

我刚刚看到这里时,感觉非常奇怪,因为不同的state,是通过对主状态的修改来实现的。比如AddChild,RemoveChild等。把currentState清空时,会回到主状态,系统会自动还原。这种方式与直接在ActionScript中改变视图元素的方式非常相似。我有点不太理解,是因为觉得这种方式太繁琐了,那么多控件,我怎么记得住。后来,在前面提到的视频中看到,人们在可视化工具中修改状态时,是直接在主状态上进行操作,如移动某元素、添加删除元素,而不是从头开始新做一个页面,那么这种方式就很自然了,因为程序可以记录下每一步操作。对于一个复杂的效果,我们很可能会利用可视化工具来实现,而不是手动编码。在这里再次感叹,Adobe不同工具之间的配合真是好。

另外,皮肤中也有states的概念。比如一个按钮,它有“正常”“悬停”“按下”“抬起”等不同的状态,可对不同状态的按钮定制外观。

关于图像与3D

使用Flex可以实现一些与图像相关的操作,这些在html5中可能比较难以实现。看下91乐印的手机外壳3D预览:

image

这是一个3D的手机模型,上面的图片是我上传的。用鼠标在窗口上拖动,则可以从各个方向看到手机的样子,挺酷的。在TourDeFlex中,也有一个类似的例子。

还有一个网站,上面用flash实现的很多3D怪兽,但网址找不到了,希望铁哥补充。

comments powered by Disqus