Flex4 实现拖拽缓动
你有在做类似Google地图这种拖拽缓动效果的应用吗?你还在为写缓动加速算法而头痛吗?如果是那么你看了下面的文章内容后你肯定会大骂一句:“TMD,原来这么简单!”。。。
费话少说,先看一下效果吧(由于是国外服务器,flash和图片加载有点慢,有请耐心等待):
效果怎么样,是不是很流畅呢!
从Demo外表可以看出他是基于Flex的Scroller组件实现的,具体代码如下:
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?> <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"> <s:Scroller width="100%" height="100%" interactionMode="touch"> <s:Group> <s:Image source="http://www.beasy.org/wp-content/uploads/2011/10/sh.jpg"/> </s:Group> </s:Scroller> </s:Application>
Demo的代码量是非常少的,关键的地方在Scroller的interactionMode样式上,interactionMode的值有两个可选:touch、mouse。interactionMode决定了Scroller的交互方式是鼠标操作还是触屏操作。
强大的Scroller内部已经做好了我们需要的功能,我们只需要设计相关的属性或样式即可。在桌面应用开发时interactionMode的值默认为mouse,在移动项目开发时interactionMode的值默认为touch。
所以我们在Flex移动项目里面使用List组件时发现它的滑动效果和iPhone的一模一样,其实这个都是Scroller大哥的功劳啊!
到此,拖拽缓动demo的功能已经完成了,是不是巨简单呢?但他长的实在太丑了,我们要给他美化一下,也就是给Scroller定制一套皮肤。
关于Flex4皮肤的制作方法这里不细说,我只给出皮肤的原码。
说到Scroller的皮肤,我这里要说一个完整的Scroller皮肤的组成部分:
- 首先是一个主skin文件,主skin包含横向和纵向两个滚动条.
- 横向和纵向滚动条都各自有自己的skin.
- 滚动条双包含:左/上移按钮、右/下移按钮、轨迹轴背景、滑动块这个四个部分.
以上每个部分的每个元素都可以各自去自定义自己的skin,以下是各个部分的skin:
1. 滚动条主体ScrollerSkin.mxml:
<?xml version="1.0" encoding="utf-8"?> <s:SparkSkin xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark"> <fx:Metadata> <![CDATA[ /** * @copy spark.skins.spark.ApplicationSkin#hostComponent */ [HostComponent("spark.components.Scroller")] ]]> </fx:Metadata> <fx:Script> <![CDATA[ /** * @private */ override public function beginHighlightBitmapCapture() : Boolean { var needUpdate:Boolean = super.beginHighlightBitmapCapture(); // Draw an opaque rect that fill our entire skin. Our background // is transparent, but we don't want focus/error skins to // poke through. This is safe to do since we don't have any // graphic elements as direct children. graphics.beginFill(0); graphics.drawRect(0, 0, width, height); graphics.endFill(); return needUpdate; } /** * @private */ override public function endHighlightBitmapCapture() : Boolean { var needUpdate:Boolean = super.endHighlightBitmapCapture(); // Clear the rect we drew in beginBitmapCapture(); graphics.clear(); return needUpdate; } ]]> </fx:Script> <s:VScrollBar id="verticalScrollBar" visible="false" skinClass="skins.VScrollBarSkin"/> <s:HScrollBar id="horizontalScrollBar" visible="false" skinClass="skins.HScrollBarSkin"/> </s:SparkSkin>
2. 横向滚动条HScrollBarSkin.mxml(因为使用拖动就不需要左右/上下移动的按扭了,所以这里皮肤把那两个按钮去掉了):
<?xml version="1.0" encoding="utf-8"?> <s:SparkSkin xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" xmlns:fb="http://ns.adobe.com/flashbuilder/2009" minWidth="35" minHeight="15" alpha.disabled="0.5" alpha.inactive="0.5"> <fx:Metadata> <![CDATA[ /** * @copy spark.skins.spark.ApplicationSkin#hostComponent */ [HostComponent("spark.components.HScrollBar")] ]]> </fx:Metadata> <s:states> <s:State name="normal" /> <s:State name="disabled" /> <s:State name="inactive" /> </s:states> <s:Button id="track" left="1" right="1" width="10" focusEnabled="false" tabEnabled="false" skinClass="skins.ScrollBarTrackSkin" /> <s:Button id="thumb" focusEnabled="false" visible.inactive="false" tabEnabled="false" mouseEnabled="false" skinClass="skins.ScrollBarThumbSkin" /> </s:SparkSkin>
3. 纵向的滚动条VScrollerSkin.mxml:
<?xml version="1.0" encoding="utf-8"?> <s:SparkSkin xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" xmlns:fb="http://ns.adobe.com/flashbuilder/2009" minWidth="15" minHeight="15" alpha.disabled="0.5" alpha.inactive="0.5" > <fx:Metadata> <![CDATA[ /** * @copy spark.skins.spark.ApplicationSkin#hostComponent */ [HostComponent("spark.components.VScrollBar")] ]]> </fx:Metadata> <s:states> <s:State name="normal" /> <s:State name="disabled" /> <s:State name="inactive" /> </s:states> <s:Button id="track" top="1" bottom="1" width="10" focusEnabled="false" tabEnabled="false" skinClass="skins.ScrollBarTrackSkin" /> <s:Button id="thumb" skinClass="skins.ScrollBarThumbSkin" mouseEnabled="false" focusEnabled="false" visible.inactive="false" tabEnabled="false"/> </s:SparkSkin>
注意这里HScrollerSkin和VScrollerSkin中的trace和thumb按钮使用的都是同一个按扭,这个是因为我横向和纵向的滚动条都是一样的外观。
4. 滚动条的轨迹ScrollerBarTrackSkin.mxml(这里轨迹没有显示任何东西,但是轨迹不能去掉,否则显示会出错,不知道为什么。)
<?xml version="1.0" encoding="utf-8"?> <s:SparkButtonSkin xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" xmlns:fb="http://ns.adobe.com/flashbuilder/2009" minWidth="10" minHeight="10" alpha.disabled="0.5"> <fx:Metadata> <![CDATA[ /** * @copy spark.skins.spark.ApplicationSkin#hostComponent */ [HostComponent("spark.components.Button")] ]]> </fx:Metadata> <s:states> <s:State name="up" /> <s:State name="over" /> <s:State name="down" /> <s:State name="disabled" /> </s:states> <s:Rect top="0" bottom="0" left="0" right="0" minWidth="10" minHeight="10"> </s:Rect> </s:SparkButtonSkin>
5. 滑动ScrollerThumbSkin.mxml:
<?xml version="1.0" encoding="utf-8"?> <s:SparkButtonSkin xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" xmlns:fb="http://ns.adobe.com/flashbuilder/2009" minWidth="10" minHeight="10" alpha.disabled="0.5"> <fx:Metadata> <![CDATA[ /** * @copy spark.skins.spark.ApplicationSkin#hostComponent */ [HostComponent("spark.components.Button")] ]]> </fx:Metadata> <s:states> <s:State name="up" /> <s:State name="over" /> <s:State name="down" /> <s:State name="disabled" /> </s:states> <s:Rect top="1" left="1" right="1" bottom="1" radiusX="5" radiusY="5"> <s:fill> <s:SolidColor color="0xC0C0C0" alpha="0.8"/> </s:fill> </s:Rect> </s:SparkButtonSkin>
最后给Scroller加上skin:
<s:Scroller width="100%" height="100%" interactionMode="touch" skinClass="skins.ScrollerSkin">
以下是加上皮肤后的效果:
留言以示支持。
如何让滚动条一直显示在哪里
好厉害
学习了
flex4中没有找到这个interactionMode属性,问一下在哪