Flex 4 beta中的视口和滚动功能介绍
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
Flex 4中的视口和滚动功能介绍
必备知识
熟悉ActionScript、Flex3和基本的2D图形概念,将有利于理解本文内容。
用户级别
中级
必需产品
Flash Builder (下载试用版)
实例下载
Download:Viewport.fxp
Flex 4提供了接口IViewport(被所有可滚动组件实现)和组件Scroller(为视口添加滚动条,实现交互时的功能)。
这里所谓视口(viewport),即可滚动组件,要实现IViewport接口。
交互式滚动,是所有图形用户界面(GUI)工具的基本特性之一。
Flex 4之所以采用这种方法,是为了比Flex 3的实现更有效率,具体请参阅Spark与MX的比较。
在List和TextArea等很多Flex组件中,Scroller和视口均是它们皮肤的一个组成部分,无需开发者考虑如何实现滚动功能。
本文将介绍IViewport接口的工作原理,并提供一个简单的Scroller例子。
如果你想知道如何创建自己的交互式滚动组件,或需深入理解Flex 4中滚动特性的工作原理,请阅读本文。
滚动与视口概述
GUI通过滚动,可以显示比用户屏幕空间更大的文档。
在Spark(Flex 4新增的组件和皮肤架构)中,IViewport接口定义了用一个矩形小裁剪窗口(clippingwindow)每次滚动一定距离、逐步展示大文档的具体行为。
这里所说“滚动”,是指改变与大文档关联的裁剪窗口的位置。
Spark中的Scroller组件为交互式滚动视口提供了一个通用的GUI。
它显示一对分别呈纵向和横向的滚动条,其滚动条的滑块位置定义了裁剪窗口的位置(X,Y)。
缺省情况下,滚动条仅在需要时才显示。
图1解释了IViewport接口的相关属性:width、height、contentWidth、contentHeight、horizontalScrollPosition和verticalScrollPosition及其几何结构。
如图1IViewport的几何结构和相关属性
视口的contentWidth和contentHeight属性,定义了视口中内容被绘制时的横向和纵向最大尺寸。
width
和height属性定义视口中部分内容的尺寸,即在屏幕上出现的内容的尺寸,或说视口的裁剪矩形窗口的大小。
horizontalScrollPosition和verticalScrollPosition属性则表示上述裁剪窗口的位置。
通过改变这些属性,应用程序可以实现视口的滚动。
Scroller类
Spark的Scroller类是一个内置视口的容器,和Group和DataGroup组件相仿。
Scroller能显示纵向和横向滚动条,其滚动位置由视口的horizontalScrollPosition和verticalScrollPosition属性表示。
滚动条滑块的长度、滚动条最大长度由视口中内容的尺寸即contentWidth和contentHeight决定。
如下是一个简单的Scroller例子。
Scroller的视口是一个Group组件,Group又包含一个位于其中央的
Image组件。
<?xml version="1.0" encoding="utf-8"?>
<s:Group xmlns:fx="/mxml/2009"
xmlns:s="library:///flex/spark"
xmlns:mx="library:///flex/mx" width="400" height="600"> <fx:Declarations>
<!--将非可视元素(例如服务、值对象)放在此处 -->
</fx:Declarations>
<s:Scroller width="300" height="400" horizontalCenter="0" verticalCenter="0"> <s:VGroup id="vp" width="100%" height="100%">
<s:Image source="assets/331598.jpg"/>
</s:VGroup>
</s:Scroller>
</s:Group>
这里还有一个经修改后更为复杂的例子,它可以显示视口几个属性的当前值
如图2显示视口几个属性的当前值
代码:
<?xml version="1.0" encoding="utf-8"?>
<s:Group xmlns:fx="/mxml/2009"
xmlns:s="library:///flex/spark"
xmlns:mx="library:///flex/mx" width="400" height="600">
<fx:Declarations>
<!--将非可视元素(例如服务、值对象)放在此处 -->
</fx:Declarations>
<s:Scroller width="300" height="400" horizontalCenter="0" verticalCenter="-50"> <s:VGroup id="vp" width="100%" height="100%">
<s:Image source="assets/331598.jpg"/>
</s:VGroup>
</s:Scroller>
<s:VGroup left="50" top="475" width="300" gap="15">
<s:Label text="viewport.contentWidth = {vp.contentWidth}"/>
<s:Label text="viewport.contentHeight = {vp.contentHeight}"/>
<s:Label text="viewport.horizontalScrollPosition =
{vp.horizontalScrollPosition}"/>
<s:Label text="viewport.verticalScrollPosition = {vp.verticalScrollPosition}"/> </s:VGroup>
</s:Group>
根据Scroller再次修改后的代码
<?xml version="1.0" encoding="utf-8"?>
<s:Group xmlns:fx="/mxml/2009"
xmlns:s="library:///flex/spark"
xmlns:mx="library:///flex/mx" width="400" height="600">
<fx:Declarations>
<!--将非可视元素(例如服务、值对象)放在此处 -->
</fx:Declarations>
<s:VGroup id="vp" width="300" height="400" horizontalCenter="0" verticalCenter="-50" clipAndEnableScrolling="true">
<s:Image source="@Embed('assets/331598.jpg')"/>
</s:VGroup>
<s:VGroup left="99" top="474" gap="15">
<s:Label text="viewport.contentWidth = {vp.contentWidth}"/>
<s:Label text="viewport.contentHeight = {vp.contentHeight}"/>
<s:Label text="viewport.horizontalScrollPosition =
{vp.horizontalScrollPosition}"/>
<s:Label text="viewport.verticalScrollPosition = {vp.verticalScrollPosition}"/> </s:VGroup>
<s:VScrollBar viewport="{vp}" height="400" left="353" top="50"/>
<s:HScrollBar viewport="{vp}" width="309" left="50" top="452"/>
</s:Group>
缺省情况下,Scroller仅在视口内容的尺寸大于视口实际尺寸时才显示滚动条。
当然,你也可以通过修改
verticalScrollPolicy和horizontalScrollPolicy属性来改变滚动条显示策略。
这两个属性的缺省值是auto,即根据需要决定是否显示滚动条。
其他两个取值分别是:on,总是显示滚动条;off,总是隐藏滚动条。
理解这些意思之后,我们就可以自定义滚动条,如图3视口自定义滚动条:
如图3视口自定义滚动条
视口自定义滚动条源码:
<?xml version="1.0" encoding="utf-8"?>
<s:Group xmlns:fx="/mxml/2009"
xmlns:s="library:///flex/spark"
xmlns:mx="library:///flex/mx"
width="400" height="600">
<fx:Declarations>
<!--将非可视元素(例如服务、值对象)放在此处 -->
</fx:Declarations>
<s:VGroup id="vp" width="300" height="400" horizontalCenter="0" verticalCenter="-50" clipAndEnableScrolling="true">
<s:Image source="@Embed('assets/331598.jpg')"/>
</s:VGroup>
<s:VGroup left="99" top="474" gap="15">
<s:Label text="viewport.contentWidth = {vp.contentWidth}"/>
<s:Label text="viewport.contentHeight = {vp.contentHeight}"/>
<s:Label text="viewport.horizontalScrollPosition =
{vp.horizontalScrollPosition}"/>
<s:Label text="viewport.verticalScrollPosition = {vp.verticalScrollPosition}"/> </s:VGroup>
<s:HSlider id="hslider" x="50" y="32" width="300"
change="{vp.horizontalScrollPosition = hslider.value}"
maximum="{vp.contentWidth - vp.width}" minimum="0"/>
<s:VSlider id="vslider" x="35" y="50" height="400"
change="{vp.verticalScrollPosition = vslider.value}"
maximum="{vp.contentHeight - vp.height}" minimum="0"/>
<s:VScrollBar viewport="{vp}" height="400" left="353" top="50"/>
<s:HScrollBar viewport="{vp}" width="309" left="50" top="452"/>
</s:Group>
IViewport接口和类
Group和DataGroup是Spark中的基本容器类,它们派生于共同基类GroupBase。
GroupBase内部已实现了IViewport接口,因此你在其派生类Group或DataGroup中创建的任何其他组件,均能在Scroller 中显示——Scroller只要求它的视口实现IViewport接口。
通过上面内容的讨论,对IViewport接口的大部分定义,你也不会感到陌生了:
public interface IViewport extends IVisualElement {
function get width():Number;
function get height():Number;
function get contentWidth():Number;
function get contentHeight():Number;
function get horizontalScrollPosition():Number;
function set horizontalScrollPosition(value:Number):void;
function get verticalScrollPosition():Number;
function set verticalScrollPosition(value:Number):void;
function getHorizontalScrollPositionDelta(scrollUnit:uint):Number;
function getVerticalScrollPositionDelta(scrollUnit:uint):Number;
function get clipAndEnableScrolling():Boolean;
function set clipAndEnableScrolling(value:Boolean):void;
}
视口的width和height属性代表了它的实际尺寸,contentWidth和contentHeight属性代表视口中内容的最大尺寸。
例如,假设视口中包含一个左上点位置为(10,20)的矩形(spark.primitives.Rect对象),矩形的宽、高均设置为100,那么视口的contentWidth应该是110,contentHeight是120。
在前面的例子中,Image的原点是(0,0)(缺省),因此Group的contentWidth和contentHeight分别与Image的宽、高相同。
Boolean属性clipAndEnableScrolling可用于控制滚动功能的开/关。
如设置为false,则视口不支持滚动。
GroupBase中的clipAndEnableScrolling默认设置为false,因此若你要从GroupBase派生可滚动容器,必须显示设置此属性为true。
Scroller则自动为其视口设置cllipAndEnableScrolling属性为true。
开启时滚动功能时,需为视口的可见部分分配内存,并且因为数值计算误差和图像修边,视口内的文本和图像有时候会发生少许错位,因此默认禁用了滚动功能。
IViewport接口的getHorizontalScrollPositionDelta和getVerticalScrollPositionDelta方法用于计算用户点击Scroller的滚动条、up/down按钮、滚动鼠标滚轮、在键盘上按下PageUp/PageDown或箭头键时,滚动条需移动的距离。
Spark与MX的比较
Spark的视口和滚动API与MX较为类似。
都提供了基础的容器类(MX中是Container,Spark中是Group 和DataGroup)用于支持滚动功能。
但和Spark不同的是,MX中的所有容器缺省都支持滚动,无需依靠专门的滚动容器添加滚动条。
在MX中,如果容器的内容尺寸超出本身大小,滚动条会根据容器的scrollPolicy属性的设定策略出现。
之所以在Spark有所改变,是为了降低应用运行时的尺寸和复杂性。
大多数应用中的大多数容器,是不需要滚动功能的,而在MX中,所有容器都具备这个能力,显然增加了程序耗用的内存大小和复杂性。
Flex 4 中引入的新策略,有时候又称为现收现付(as pay as you go),意思是仅仅在你需要这种SDK特性时,你的应用才应该在运行时尺寸和复杂度上付出相应代价。
总结
IViewport接口和Scroller类的使用和扩展方法,其实还包含很多内容。
在Evtim Georgiev的博客上发表相关文章。
如想更多了解Spark布局规则、语法和用例等方面内容,也可在线阅读相关文档。
若需进一步了解视口、滚动相关API,请阅读Flex 4 Language Reference中IViewport、Scroller、GroupBase、Group、DataGroup等类的内容。
也请关注Evtim Georgiev的博客,其主要内容紧扣界面布局、可视化等方面。
-----------------------------
以上部分文档摘自:Adobe 开发人员中心博客,详见原文:
/cn/devnet/flex/articles/flex4_viewport_scrolling.html。