• Flash/Flex学习笔记(36):自己动手实现一个滑块控件(JimmySilder)


    先看最终的演示:

    滑块条的应用实在太广泛了:mp3播放器中声量的大小控制,视频播放时的画面亮度调节,阅读新闻时字体大小的实时调整,对象的大小互动控制...

    分析:

    1.任何一个滑块条控件的UI部分,基本上可以分为:背景滑块条 + 滑块按钮 二个部分

    所以我分成了三部分: JimmySilderBar(背景条),JimmySilderButton(拖动钮),JimmySilder(真正的滑动控件,将前二个组合在一起),为了重用,这三个部分都做成MovieClip元件放在库里,这样以后要换风格或颜色时,只要在库里编辑元件,所有的地方自然全变了.

    另外在JimmySilder这个元件中,为了能在代码中引用到另外二个元件的实例,JimmySilderButton实例被命名为_mcBtn,而JimmySilderBar实例被命名为_mcBar

    2.拖动问题

    MovieClip有startDrag/endDrag方法,而且startDarg方法还能方便的设置拖动的边界(即拖动时,滑块钮不能拖到背景条以外的地方),so...这个问题也解决了

    3.属性/事件支持

    既然是滑块控件,肯定要能得到当前的位置/值,另外拖动(以导致值变化)时,应该能触发使用者自己定义的处理方法(否则就变成一个单纯只能拖来拖去的东东,不能跟其它对象的属性关联交互,那就没啥意义了)

    实现:

    1.为了支持事件,首先也定义一个Event子类:

    view source

    print?

    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.控件代码的实现:

    view source

    print?

    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.测试代码:

    view source

    print?

    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左右),所以还是那句话,能自己手写的就自己手写,除非自己写不了,再用系统的组件。

  • 相关阅读:
    用记事本编写一个Servlet项目
    Servlet开发(一)
    41、java与mysql乱码的问题
    40、JDBC相关概念介绍
    mysql-5.7.12-winx64安装版配置、使用
    39、集合线程安全问题
    38、各Set实现类的性能分析
    电脑取随机数是什么原理,是真正的随机数吗?转自知乎.
    创建Car类,实例化并调用Car类计算运输的原料量是否足够
    用Random类输出验证码
  • 原文地址:https://www.cnblogs.com/happysky97/p/1884570.html
Copyright © 2020-2023  润新知