本文转自:http://www.cnblogs.com/zhoujunfeng2011/archive/2011/07/15/2106989.html
AS3.0 实现自定义滚动条(滚动内容可以为Sprite 或 MovieClip等),修改属性类型即可!
源码:
Scrollbar.as
package ui
{
import flash.display.Sprite;
import flash.events.MouseEvent;
import flash.events.Event;
import ui.ListenManager;
import flash.geom.Rectangle;
public class Scrollbar extends Sprite
{
public var obj:Sprite;//需进行滚动的对象
public var scrollmask:Sprite;//遮罩对象
public var scrollheight:Number;//滚动条高度
public var scrolltextnum:int;//文本显示行数
public var textspeed:int;//文本滚动速度(行/像素)
public var Scroll:Sprite;//自定义滚动条对象
public var bar:Sprite;//滑块
public var up:Sprite;//向上按钮
public var down:Sprite;//向下按钮
public var bg:Sprite;//滑槽
public var displayobject:*;//接受stage,必须传入
public var num:int;//计算滑块高度所用
private var bars:Number;//滑块可滑动距离
private var rect:Rectangle;//滑块可拖动范围
private var i:int = 0;
private var n:Number;
private var listenmanager:ListenManager = new ListenManager();///监听管理器
构造器函数/
public function Scrollbar():void
{
}
/初始化函数/
public function init():void
{
if (checkhide())
{
addEventListeners();
}
else
{
bar.visible = false;
}
setxy();
}
///判断是否显示滚动条等///
private function checkhide():Boolean
{
if (Scroll != null)
{
if (obj.height <= scrollmask.height)
{
return false;
}
return true;
}
return false;
}
///设置滚动条高度,对象遮罩等
private function setxy():void
{
up.y = 1;
bg.y = up.height;
bar.x = 1.2;
bar.y = bg.y;
if (bar.height >= 10)
{
n = (obj.height - scrollmask.height)/(num+20);
bar.height = scrollmask.height - (obj.height - scrollmask.height)/n;
}
bg.height = scrollheight;
down.y = bg.y + bg.height;
bars = bg.height - bar.height;
obj.mask = scrollmask;
rect = new Rectangle(bar.x,bg.y,0,bg.height - bar.height);
}
///当被滚动对象更新时,而需要改变滚动条状态,调用此方法///
public function update(num:int):void
{
if (checkhide())
{
i++;
if (bar.height >= 10)
{
n = (obj.height - scrollmask.height)/(num+20);
bar.height = scrollmask.height - (obj.height - scrollmask.height)/n;
}
bar.y = bg.y + bg.height - bar.height;
bar.y += bars * textspeed /(obj.height - scrollmask.height);
obj.y = scrollmask.y - obj.height + scrollmask.height;
objrun(textspeed);
updatebar();
bars = bg.height - bar.height;
rect = new Rectangle(bar.x,bg.y,0,bg.height - bar.height);
if (i == 1)
{
bar.visible = true;
addEventListeners();
}
}
}
///为滚动条添加监听事件
private function addEventListeners():void
{
listenmanager.fcn_add(bar,MouseEvent.MOUSE_DOWN,barclick);
listenmanager.fcn_add(bar,MouseEvent.MOUSE_UP,barup);
listenmanager.fcn_add(displayobject,MouseEvent.MOUSE_UP,barup);
listenmanager.fcn_add(up,MouseEvent.MOUSE_DOWN,upclick);
listenmanager.fcn_add(down,MouseEvent.MOUSE_DOWN,downclick);
listenmanager.fcn_add(Scroll,MouseEvent.MOUSE_WHEEL,mousewheel);
listenmanager.fcn_add(obj,MouseEvent.MOUSE_WHEEL,mousewheel);
}
///鼠标点击滑块方法///;
private function barclick(evt:MouseEvent):void
{
bar.startDrag(false,rect);
listenmanager.fcn_add(bar,Event.ENTER_FRAME,bar_enter_frame);
}
///鼠标点击滑块释放方法///;
private function barup(evt:MouseEvent):void
{
bar.stopDrag();
delevent();
}
///鼠标点击向上按钮方法///
private function upclick(evt:MouseEvent):void
{
if (checkbar())
{
bar.y -= bars * textspeed /(obj.height-scrollmask.height);//滑块移动的距离=滚动对象滚动的像素*滑块可移动的总距离/(被滚动对象的高度-遮罩的高度(即显示范围的高度))
objrun(0-textspeed);
//调用方法移动对象;
updatebar();//校正滑块位置
}
}
///鼠标点击向下按钮方法///
private function downclick(evt:MouseEvent):void
{
if (checkbar())
{
bar.y += bars * textspeed /(obj.height - scrollmask.height);
objrun(textspeed);
updatebar();
}
}
///鼠标滑轮事件///
private function mousewheel(evt:MouseEvent):void
{
if (evt.delta > 0)
{
if (checkbar())
{
bar.y -= bars * textspeed /(obj.height - scrollmask.height);
objrun(-textspeed);
updatebar();
}
}
else
{
if (checkbar())
{
bar.y += bars * textspeed /(obj.height - scrollmask.height);
objrun(textspeed);
updatebar();
}
}
}
private function bar_enter_frame(evt:Event):void
{
obj.y = scrollmask.y - (bar.y - bg.y)*(obj.height - scrollmask.height)/bars;
if (obj.y > scrollmask.y)
{
obj.y = scrollmask.y;
}
else if (obj.y < (scrollmask.y - obj.height + scrollmask.height))
{
obj.y = scrollmask.y - obj.height + scrollmask.height;
}
}
private function objrun(i:Number):void
{
obj.y -= i;
if (obj.y > scrollmask.y)
{
obj.y = scrollmask.y;
}
else if (obj.y < (scrollmask.y - obj.height + scrollmask.height))
{
obj.y = scrollmask.y - obj.height + scrollmask.height;
}
}
private function checkbar():Boolean
{
if (bar.y >= bg.y && bar.y <= (bars + bg.y))
{
return true;
}
return false;
}
///删除卸载事件侦听///
private function updatebar():void
{
if (bar.y < bg.y)
{
bar.y = bg.y;
}
else if (bar.y >(bg.y + bg.height - bar.height))
{
bar.y = bg.y + bg.height - bar.height;
}
}
private function delevent():void
{
listenmanager.fcn_del(bar,Event.ENTER_FRAME,bar_enter_frame);
}
}
}
ListenManager.as
package ui
{
import flash.display.Sprite;
public class ListenManager extends Sprite
{
public function ListenManager()
{
}
public function fcn_add(obj:*,_type:String,fcn:Function):void
{
obj.addEventListener(_type,fcn);
}
public function fcn_del(obj:*,_type:String,fcn:Function):void
{
obj.removeEventListener(_type,fcn);
}
}
}
package ui
{
import flash.display.Loader;
public class loader extends Loader
{
private var Name:String;
public function loader():void
{
}
public function get Names():String
{
return Name;
}
public function set Names(myname:String):void
{
Name = myname;
}
}
}
package ui
{
import flash.display.Sprite;
import flash.display.SimpleButton;
import flash.text.TextField;
import flash.text.TextFormat;
import flash.text.TextFieldAutoSize;
public class simple extends Sprite
{
private var btnw:Number;
private var btnh:Number;
private var downcolor:uint;
private var upcolor:uint;
private var overcolor:uint;
private var lineStly:Boolean;
public function simple():void
{
}
public function getsimplebtn(str:String,btnw:Number = 50,btnh:Number = 30,downcolor:uint = 0x990066,upcolor:uint = 0xffffff,overcolor:uint = 0x666666,lineStly:Boolean = false):SimpleButton
{
this.name = str;
this.btnw = btnw;
this.btnh = btnh;
this.downcolor = downcolor;
this.upcolor = upcolor;
this.overcolor = overcolor;
this.lineStly = lineStly;
var btn:SimpleButton = new SimpleButton();
btn.downState = downbtn();
btn.upState = upbtn();
btn.overState = overbtn();
btn.hitTestState = hitbtn();
return btn;
}
private function hitbtn():Sprite
{
var sprite:Sprite = new Sprite();
sprite.graphics.beginFill(upcolor);
sprite.graphics.drawRect(0,0,btnw,btnh);
sprite.graphics.endFill();
return sprite;
}
private function downbtn():Sprite
{
var txt:TextField = txtstr(this.name);
var sprite:Sprite = DrawSprite(1);
sprite.addChild(txt);
return sprite;
}
private function upbtn():Sprite
{
var txt:TextField = txtstr(this.name);
var sprite:Sprite = DrawSprite(0);
sprite.addChild(txt);
return sprite;
}
private function overbtn():Sprite
{
var txt:TextField = txtstr(this.name);
var sprite:Sprite = DrawSprite(2);
sprite.addChild(txt);
return sprite;
}
private function txtstr(str:String):TextField
{
var txt:TextField = new TextField();
var format:TextFormat = new TextFormat();
format.font = "Verdana";
format.size = 12;
txt.autoSize = TextFieldAutoSize.LEFT;
txt.text = str;
txt.setTextFormat(format);
return txt;
}
private function DrawSprite(n:int):Sprite
{
var sprite:Sprite = new Sprite();
if (n == 0)
{
sprite.graphics.beginFill(upcolor);
}
else if (n == 1)
{
sprite.graphics.beginFill(downcolor);
}
else if (n == 2)
{
sprite.graphics.beginFill(overcolor);
}
if(lineStly)
{
sprite.graphics.lineStyle(1,0x660099);
}
sprite.graphics.drawRect(0,0,btnw,btnh);
sprite.graphics.endFill();
return sprite;
}
}
}
文档类:Main.as
package
{
import flash.display.Sprite;
import ui.simple;
import ui.Scrollbar;
import flash.display.SimpleButton;
import flash.events.MouseEvent;
import flash.display.Shape;
import flash.net.URLLoader;
import flash.events.Event;
import flash.net.URLRequest;
import ui.loader;
import flash.display.Bitmap;
import flash.text.TextField;
public class Main extends Sprite
{
private var backbox:Sprite = new Sprite();
private var sprite:Sprite = new Sprite();
private var scrollcont:Sprite = new Sprite();
private var i:int = 0;
private var j:int = -1;
private var num:int;
private var bg:Sprite = new Sprite();
private var bar:Sprite = new Sprite();
private var up:Sprite = new Sprite();
private var down:Sprite = new Sprite();
private var listscroll:Scrollbar = new Scrollbar();
public function Main():void
{
init();
}
private function init():void
{
var urlloader:URLLoader = new URLLoader();
urlloader.addEventListener(Event.COMPLETE,com);
urlloader.load(new URLRequest("http://files.cnblogs.com/zhoujunfeng2011/Pictures/data.xml"));
}
private function com(evt:Event):void
{
var myxml:XML = new XML(evt.target.data);
num = myxml.child("pic").length();
for (var i:int =0; i<num; i++)
{
var myloader:loader = new loader();
myloader.contentLoaderInfo.addEventListener(Event.COMPLETE,piccom);
myloader.load(new URLRequest(myxml.child("pic")[i].@url));
myloader.Names = myxml.child("pic")[i]. @ name;
}
}
private function piccom(evt:Event):void
{
j++;
var myloader:loader = loader(evt.target.loader);
var bitmap:Bitmap = Bitmap(myloader.content);
var sprite:Sprite = new Sprite();
sprite.addChild(bitmap);
switch (myloader.Names)
{
case "滑块" :
bar = sprite;
break;
case "滑槽" :
bg = sprite;
break;
case "向上" :
up = sprite;
break;
case "向下" :
down = sprite;
break;
}
if (j == num-1)
{
uiinit();
}
}
private function uiinit():void
{
var btn:simple = new simple();
var spmask:Sprite = new Sprite();
var Test_btn:SimpleButton;
backbox.graphics.beginFill(0xffffff);
backbox.graphics.lineStyle(1,0x660099);
backbox.graphics.drawRect(0,0,200,241);
backbox.graphics.endFill();
backbox.y = 10;
addChild(backbox);
scrollcont.x = backbox.width - 14;
scrollcont.y = backbox.y;
addChild(scrollcont);
down.y = scrollcont.y;
scrollcont.addChild(down);
scrollcont.addChild(bg);
scrollcont.addChild(up);
scrollcont.addChild(bar);
spmask.graphics.beginFill(0x000000);
spmask.graphics.drawRect(0,0,backbox.width,backbox.height);
spmask.graphics.endFill();
backbox.addChild(sprite);
backbox.addChild(spmask);
Test_btn = btn.getsimplebtn("点击添加",60,30,0xff00cc,0xcc00cc,0x9900cc);
Test_btn.x = 65;
Test_btn.y = backbox.height + 15;
this.addChild(Test_btn);
for (i; i< 120; i++)
{
var sbtn:simple = new simple();
var sp:SimpleButton;
var str:String = i + 1 + " this is Testing!";
sp = sbtn.getsimplebtn(str,185,20,0x990099,0x66ffff,0x99ffff,true);
sp.x = 1;
sp.y = i * 20;
sprite.addChild(sp);
}
listscroll.displayobject = this.stage;
listscroll.obj = sprite;
listscroll.scrollmask = spmask;
listscroll.textspeed = 20;
listscroll.Scroll = scrollcont;
listscroll.scrollheight = 212;
listscroll.up = up;
listscroll.down = down;
listscroll.bg = bg;
listscroll.bar = bar;
listscroll.num = i;
listscroll.init();
Test_btn.addEventListener(MouseEvent.CLICK,Testbtn_click);
}
private function Testbtn_click(evt:MouseEvent):void
{
var sbtn:simple = new simple();
var sp:SimpleButton;
var str:String = i + 1 + " this is Testing!";
sp = sbtn.getsimplebtn(str,185,20,0x990099,0x66ffff,0x99ffff,true);
sp.x = 1;
sp.y = i * 20;
sprite.addChild(sp);
listscroll.update(i);
i++;
}
}
}
为图方便所以使用了SimpleButton类型作为列表中的内容,


<?xml version="1.0" encoding="utf-8"?>
<data>
<pic name="滑槽" url="http://files.cnblogs.com/zhoujunfeng2011/Pictures/bg.png"/>
<pic name="向上" url="http://files.cnblogs.com/zhoujunfeng2011/Pictures/up.png"/>
<pic name="向下" url="http://files.cnblogs.com/zhoujunfeng2011/Pictures/down.png"/>
<pic name="滑块" url="http://files.cnblogs.com/zhoujunfeng2011/Pictures/bar.png"/>
</data>