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

简介: 先看最终的演示: 滑块条的应用实在太广泛了:mp3播放器中声量的大小控制,视频播放时的画面亮度调节,阅读新闻时字体大小的实时调整,对象的大小互动控制... 分析: 1.任何一个滑块条控件的UI部分,基本上可以分为:背景滑块条 + 滑块按钮 二个部分 所以我分成了三部分: J...

先看最终的演示:

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

分析:

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

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

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

img_7466cffa6a657fd990e9111dec08bc61.jpg

2.拖动问题

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

3.属性/事件支持

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

实现:

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

package Jimmy.Event {
	import flash.events.Event;

	public class ValueChangeEvent extends Event {		
		public static const VALUE_CHANGE:String = "VALUE_CHANGE";		
		private var _OldValue:Number,_NewValue:Number;
		
		public function ValueChangeEvent(eventType:String,oldValue:Number,newValue:Number){
			this._OldValue = oldValue;
			this._NewValue = newValue;
			super(eventType);
		}
		
		public function get OldValue():Number{
			return _OldValue;
		}
		
		public function get NewValue():Number{
			return _NewValue;
		}
	}
}

2.控件代码的实现:

//滑块控件 beta 0.001 -- by 菩提树下的杨过 http://yjmyzz.cnblogs.com/
package {
	import flash.display.Sprite;
	import flash.display.MovieClip;
	import flash.events.MouseEvent;
	import flash.ui.Mouse;
	import flash.events.Event;
	import flash.ui.MouseCursor;
	import flash.geom.Rectangle;
	import Jimmy.Event.ValueChangeEvent;

	public class JimmySilder extends MovieClip {

		private var _btnWidth:uint;//滑块宽度
		private var _btnHeight:uint;//滑块高度
		private var _barWidth:uint;//滑块背景条宽度
		private var _barHeight:uint;//滑块背景条高度
		private var _isDragging:Boolean=false;//是否正在拖动
		private var _value:Number=0.0;//滑块的值(百分比)

		public function JimmySilder(btnWidth:uint = 10,btnHeight:uint = 30,barWidth:uint=200,barHeight:uint=10,v:Number=0.5):void {

			//trace("JimmySilder's constructor is called.");

			this._btnWidth=btnWidth;
			this._btnHeight=btnHeight;
			this._barWidth=barWidth;
			this._barHeight=barHeight;

			init();

			this.Value=v;
			
			this.addEventListener(Event.ADDED_TO_STAGE,AddedToStage);
			
			
		}
		
		private function AddedToStage(e:Event):void{
			this.stage.addEventListener(MouseEvent.MOUSE_MOVE,stageMouseMoveHandler);
			this.stage.addEventListener(MouseEvent.MOUSE_UP,stageMouseUpHandler);
		}

		//属性Value的setter方法
		public function set Value(v:Number):void {
			if (v<=0) {
				v=0.0;
			}
			if (v>=1) {
				v=1.0;
			}
			this._value=v;
			this._mcBtn.x = _mcBar.width/(-2) + _mcBar.width * _value;//根据value百分比值来定位mcBtn的横坐标
		}

		//属性Value的getter方法
		public function get Value():Number {
			return _value;
		}
		
		//初始化
		private function init():void {
			this._mcBtn.width=_btnWidth;
			this._mcBtn.height=_btnHeight;
			this._mcBar.width=_barWidth;
			this._mcBar.height=_barHeight;

			this._mcBtn.addEventListener(MouseEvent.MOUSE_OVER, mcBtnMouseOverHandler);
			this._mcBtn.addEventListener(MouseEvent.MOUSE_OUT, mcBtnMouseOutHandler);
			this._mcBtn.addEventListener(MouseEvent.MOUSE_DOWN,mcBtnMouseDownHandler);			

			this._mcBar.addEventListener(MouseEvent.MOUSE_DOWN,mcBarMouseDownHandler);
			//trace("init 初始化完成");
		}
		
		//切换光标为手形
		private function mcBtnMouseOverHandler(e:MouseEvent) {
			Mouse.cursor=MouseCursor.HAND;
		}

		//切换光标为系统光标
		private function mcBtnMouseOutHandler(e:MouseEvent) {
			Mouse.cursor=MouseCursor.AUTO;
		}

		//开始拖动
		private function mcBtnMouseDownHandler(e:MouseEvent) {
			//trace("开始拖动");
			_mcBtn.startDrag(true,new Rectangle(_mcBar.width/(-2),0,_mcBar.width,0));//注意:这里锁定中心在指定区域拖动
			_isDragging=true;
		}

		//停止拖动
		private function stageMouseUpHandler(e:MouseEvent) {
			//trace("停止拖动");
			_mcBtn.stopDrag();
			_isDragging=false;
		}

		//在自身区域上移动时,动态计算_value值
		private function stageMouseMoveHandler(e:MouseEvent) {
			if (_isDragging) {
				RaiseEvent();
				//trace(_value);
			}
		}

		

		//在背景条上点击时,滑块直接跳到该位置
		private function mcBarMouseDownHandler(e:MouseEvent) {
			_mcBtn.x=mouseX;
			RaiseEvent();
		}
		
		//触发事件
		private function RaiseEvent():void {
			var _oldValue:Number=_value;
			_value = (_mcBtn.x + _mcBar.width/2)/_mcBar.width;
			var _valueChangeEvent:ValueChangeEvent=new ValueChangeEvent(ValueChangeEvent.VALUE_CHANGE,_oldValue,_value);
			dispatchEvent(_valueChangeEvent);//触发事件  
		}
	}
}

3.测试代码:

import Jimmy.Event.ValueChangeEvent;

var silder:JimmySilder = new JimmySilder();

silder.width = 200;
silder.height = 20;
silder.x = stage.stageWidth/2;
silder.y = 200;

//trace(silder.Value);

addChild(silder);

silder.addEventListener(ValueChangeEvent.VALUE_CHANGE, ValueChangeHandler);

testObj.scaleX = testObj.scaleY = silder.Value;

testObj2.rotation = silder.Value * 360;

function ValueChangeHandler(e:ValueChangeEvent){
	//trace("当前滑块的值是:" + e.NewValue);	
	testObj.scaleX = testObj.scaleY = e.NewValue;
	
	testObj2.rotation = silder.Value * 360;
}

源文件下载: http://cid-2959920b8267aaca.skydrive.live.com/self.aspx/Flash/JimmySilder.rar

后记:可能有人会问,为啥不直接用系统内置的组件,要费这么大劲自己重造轮子? 如果您自己试下就会知道了,用了系统组件后,swf文件大约会在19k或22k,而按本文的办法,同样的swf,最终只有7K(精简了1/3左右),所以还是那句话,能自己手写的就自己手写,除非自己写不了,再用系统的组件。

目录
相关文章
|
30天前
|
前端开发 JavaScript 开发者
【QML进阶 进度条设计】打造动态弧形进度条特效
【QML进阶 进度条设计】打造动态弧形进度条特效
84 1
|
4月前
|
C++ UED
C++ Qt开发:Slider滑块条组件
Qt 是一个跨平台C++图形界面开发库,利用Qt可以快速开发跨平台窗体应用程序,在Qt中我们可以通过拖拽的方式将不同组件放到指定的位置,实现图形化开发极大的方便了开发效率,本章将重点介绍`Slider`滑块条组件的常用方法及灵活运用。当涉及到C++ Qt开发中的`Slider`滑块条组件时,你可能会用到`QSlider`类。`QSlider`是一个用于选择整数值的控件,常用于调整范围内的数值,如音量、亮度等。在水平方向上的`Slider`通常被称为水平滑块(Horizontal Slider),而在垂直方向上的Slider被称为垂直滑块(Vertical Slider)。
35 0
|
Web App开发 前端开发 程序员
好程序员web前端教程分享3种方法实现CSS隐藏滚动条并可以滚动内容
好程序员web前端教程分享3种方法实现CSS隐藏滚动条并可以滚动内容,隐藏滚动条的同时还需要支持滚动,我们经常在前端开发中遇到这种情况,最容易想到的是加一个iscroll插件,但其实现在CSS也可以实现这个功能,我已经在很多地方使用了,下面一起看看这三种方法。
1579 0
|
C#
WPF一步步实现完全无边框自定义Window(附源码)
原文:WPF一步步实现完全无边框自定义Window(附源码)    在我们设计一个软件的时候,有很多时候我们需要按照美工的设计来重新设计整个版面,这当然包括主窗体,因为WPF为我们提供了强大的模板的特性,这就为我们自定义各种空间提供了可能性,这篇博客主要用来介绍如何自定义自己的Window,在介绍整个写作思路之前,我们来看看最终的效果。
1226 0
通通玩blend美工(6)上——仿iPhone滚动选择器的ListBox(UI设计)
原文:通通玩blend美工(6)上——仿iPhone滚动选择器的ListBox(UI设计)       好久没更新博客了,由于项目比较紧,期间收到不少园友的短消息,感谢大家对我的支持~~。   相信各位都在自己的神机中看到过各种滚动选择器,偶们项目经理就是个iPhone迷,前几天一直抬着个手机对我说"这个炫,做这个...".于是就有了这个选择器。
1034 0
|
算法 C# iOS开发
通通玩blend美工(6)下——仿iPhone滚动选择器的ListBox(交互逻辑)
原文:通通玩blend美工(6)下——仿iPhone滚动选择器的ListBox(交互逻辑)       上一篇我们已经把界面画出来了,这篇我们就来制作交互的逻辑吧。上一篇的电梯: http://www.
960 0
|
C#
WPF ScrollViewer(滚动条) 自定义样式表制作 (改良+美化)
原文:WPF ScrollViewer(滚动条) 自定义样式表制作 (改良+美化) 注释直接写在代码里了   不太理解意思的 可以先去看看我上一篇  WPF ScrollViewer(滚动条)  自定义样式表制作 图文并茂 滚动条因为要在触摸屏上用  所以我设计的很宽 宽度可以自己改  把宽度变量...
2003 0
|
C#
WPF ScrollViewer(滚动条) 自定义样式表制作 再发一套样式 细节优化
原文:WPF ScrollViewer(滚动条) 自定义样式表制作 再发一套样式 细节优化   艾尼路 出的效果图 本人嵌套  WPF ScrollViewer(滚动条) 自定义样式表制作 图文并茂 WPF ScrollViewer(滚动条) 自定义样式表制作 (改良+美化) ...
1592 0
|
C#
WPF ScrollViewer(滚动条) 自定义样式表制作 图文并茂
原文:WPF ScrollViewer(滚动条) 自定义样式表制作 图文并茂 先上效果图 正常样式 拖动时样式 好下面 开始吧 ================================================================= 打开blend 新建...
1538 0