先看最终的演示:
滑块条的应用实在太广泛了:mp3播放器中声量的大小控制,视频播放时的画面亮度调节,阅读新闻时字体大小的实时调整,对象的大小互动控制...
分析:
1.任何一个滑块条控件的UI部分,基本上可以分为:背景滑块条 + 滑块按钮 二个部分
所以我分成了三部分: JimmySilderBar(背景条),JimmySilderButton(拖动钮),JimmySilder(真正的滑动控件,将前二个组合在一起),为了重用,这三个部分都做成MovieClip元件放在库里,这样以后要换风格或颜色时,只要在库里编辑元件,所有的地方自然全变了.
另外在JimmySilder这个元件中,为了能在代码中引用到另外二个元件的实例,JimmySilderButton实例被命名为_mcBtn,而JimmySilderBar实例被命名为_mcBar
2.拖动问题
MovieClip有startDrag/endDrag方法,而且startDarg方法还能方便的设置拖动的边界(即拖动时,滑块钮不能拖到背景条以外的地方),so...这个问题也解决了
3.属性/事件支持
既然是滑块控件,肯定要能得到当前的位置/值,另外拖动(以导致值变化)时,应该能触发使用者自己定义的处理方法(否则就变成一个单纯只能拖来拖去的东东,不能跟其它对象的属性关联交互,那就没啥意义了)
实现:
1.为了支持事件,首先也定义一个Event子类:
01
package
Jimmy.Event {
02
import
flash.events.Event;
03
04
public
class
ValueChangeEvent
extends
Event {
05
public
static
const
VALUE_CHANGE:
String
=
"VALUE_CHANGE"
;
06
private
var
_OldValue:
Number
,_NewValue:
Number
;
07
08
public
function
ValueChangeEvent(eventType:
String
,oldValue:
Number
,newValue:
Number
){
09
this
._OldValue = oldValue;
10
this
._NewValue = newValue;
11
super
(eventType);
12
}
13
14
public
function
get
OldValue():
Number
{
15
return
_OldValue;
16
}
17
18
public
function
get
NewValue():
Number
{
19
return
_NewValue;
20
}
21
}
22
}
2.控件代码的实现:
001
//滑块控件 beta 0.001 -- by 菩提树下的杨过 http://yjmyzz.cnblogs.com/
002
package
{
003
import
flash.display.Sprite;
004
import
flash.display.MovieClip;
005
import
flash.events.MouseEvent;
006
import
flash.ui.Mouse;
007
import
flash.events.Event;
008
import
flash.ui.MouseCursor;
009
import
flash.geom.Rectangle;
010
import
Jimmy.Event.ValueChangeEvent;
011
012
public
class
JimmySilder
extends
MovieClip {
013
014
private
var
_btnWidth:
uint
;
//滑块宽度
015
private
var
_btnHeight:
uint
;
//滑块高度
016
private
var
_barWidth:
uint
;
//滑块背景条宽度
017
private
var
_barHeight:
uint
;
//滑块背景条高度
018
private
var
_isDragging:
Boolean
=
false
;
//是否正在拖动
019
private
var
_value:
Number
=
0.0
;
//滑块的值(百分比)
020
021
public
function
JimmySilder(btnWidth:
uint
=
10
,btnHeight:
uint
=
30
,barWidth:
uint
=
200
,barHeight:
uint
=
10
,v:
Number
=
0.5
):
void
{
022
023
//trace("JimmySilder's constructor is called.");
024
025
this
._btnWidth=btnWidth;
026
this
._btnHeight=btnHeight;
027
this
._barWidth=barWidth;
028
this
._barHeight=barHeight;
029
030
init();
031
032
this
.Value=v;
033
034
this
.addEventListener(Event.ADDED_TO_STAGE,AddedToStage);
035
036
037
}
038
039
private
function
AddedToStage(e:Event):
void
{
040
this
.stage.addEventListener(MouseEvent.MOUSE_MOVE,stageMouseMoveHandler);
041
this
.stage.addEventListener(MouseEvent.MOUSE_UP,stageMouseUpHandler);
042
}
043
044
//属性Value的setter方法
045
public
function
set
Value(v:
Number
):
void
{
046
if
(v<=
0
) {
047
v=
0.0
;
048
}
049
if
(v>=
1
) {
050
v=
1.0
;
051
}
052
this
._value=v;
053
this
._mcBtn.x = _mcBar.width/(-
2
) + _mcBar.width * _value;
//根据value百分比值来定位mcBtn的横坐标
054
}
055
056
//属性Value的getter方法
057
public
function
get
Value():
Number
{
058
return
_value;
059
}
060
061
//初始化
062
private
function
init():
void
{
063
this
._mcBtn.width=_btnWidth;
064
this
._mcBtn.height=_btnHeight;
065
this
._mcBar.width=_barWidth;
066
this
._mcBar.height=_barHeight;
067
068
this
._mcBtn.addEventListener(MouseEvent.MOUSE_OVER, mcBtnMouseOverHandler);
069
this
._mcBtn.addEventListener(MouseEvent.MOUSE_OUT, mcBtnMouseOutHandler);
070
this
._mcBtn.addEventListener(MouseEvent.MOUSE_DOWN,mcBtnMouseDownHandler);
071
072
this
._mcBar.addEventListener(MouseEvent.MOUSE_DOWN,mcBarMouseDownHandler);
073
//trace("init 初始化完成");
074
}
075
076
//切换光标为手形
077
private
function
mcBtnMouseOverHandler(e:MouseEvent) {
078
Mouse.cursor=MouseCursor.HAND;
079
}
080
081
//切换光标为系统光标
082
private
function
mcBtnMouseOutHandler(e:MouseEvent) {
083
Mouse.cursor=MouseCursor.AUTO;
084
}
085
086
//开始拖动
087
private
function
mcBtnMouseDownHandler(e:MouseEvent) {
088
//trace("开始拖动");
089
_mcBtn.startDrag(
true
,
new
Rectangle(_mcBar.width/(-
2
),
0
,_mcBar.width,
0
));
//注意:这里锁定中心在指定区域拖动
090
_isDragging=
true
;
091
}
092
093
//停止拖动
094
private
function
stageMouseUpHandler(e:MouseEvent) {
095
//trace("停止拖动");
096
_mcBtn.stopDrag();
097
_isDragging=
false
;
098
}
099
100
//在自身区域上移动时,动态计算_value值
101
private
function
stageMouseMoveHandler(e:MouseEvent) {
102
if
(_isDragging) {
103
RaiseEvent();
104
//trace(_value);
105
}
106
}
107
108
109
110
//在背景条上点击时,滑块直接跳到该位置
111
private
function
mcBarMouseDownHandler(e:MouseEvent) {
112
_mcBtn.x=mouseX;
113
RaiseEvent();
114
}
115
116
//触发事件
117
private
function
RaiseEvent():
void
{
118
var
_oldValue:
Number
=_value;
119
_value = (_mcBtn.x + _mcBar.width/
2
)/_mcBar.width;
120
var
_valueChangeEvent:ValueChangeEvent=
new
ValueChangeEvent(ValueChangeEvent.VALUE_CHANGE,_oldValue,_value);
121
dispatchEvent(_valueChangeEvent);
//触发事件
122
}
123
}
124
}
3.测试代码:
01
import
Jimmy.Event.ValueChangeEvent;
02
03
var
silder:JimmySilder =
new
JimmySilder();
04
05
silder.width =
200
;
06
silder.height =
20
;
07
silder.x = stage.stageWidth/
2
;
08
silder.y =
200
;
09
10
//trace(silder.Value);
11
12
addChild(silder);
13
14
silder.addEventListener(ValueChangeEvent.VALUE_CHANGE, ValueChangeHandler);
15
16
testObj.scaleX = testObj.scaleY = silder.Value;
17
18
testObj2.rotation = silder.Value *
360
;
19
20
function
ValueChangeHandler(e:ValueChangeEvent){
21
//trace("当前滑块的值是:" + e.NewValue);
22
testObj.scaleX = testObj.scaleY = e.NewValue;
23
24
testObj2.rotation = silder.Value *
360
;
25
}
源文件下载: http://cid-2959920b8267aaca.skydrive.live.com/self.aspx/Flash/JimmySilder.rar
后记:可能有人会问,为啥不直接用系统内置的组件,要费这么大劲自己重造轮子? 如果您自己试下就会知道了,用了系统组件后,swf文件大约会在19k或22k,而按本文的办法,同样的swf,最终只有7K(精简了1/3左右),所以还是那句话,能自己手写的就自己手写,除非自己写不了,再用系统的组件。