在Flex中实现自定义的Caret

Flex中只有TextField组件实现了Caret,即插入位置的显示功能。最近研究Editor,自己实现了一个Caret类。

难点:如何按固有频率切换状态(显示--擦除)

大家知道Flex中,用Timer触发定期事件不准确,因此使用Timer处理Caret状态,自然也有类似问题。经试验确实存在此问题,需另寻途径。

还要回到Timer定时器上,如果我们定义一个间隔非常短的定时器,对系统时间进行轮询,有了系统时间,而且在极短的时间内如毫秒级,几乎可以认为是连续的“Thread”了。只要能记住第一次显示Caret的时间,就可以在擦除时刻或下一个显示时刻进行相应的操作。

最终效果不错。

代码如下:


package
{
import flash.events.TimerEvent;
import flash.utils.Timer;

import mx.core.UIComponent;

public class Caret extends UIComponent
{
private static var DELAY:uint = 700; //mileseconds
private static var PERIOD:uint = 1000; //mileseconds
private static var DELTA:uint = 20;
private var startTime:Date;

private var started:Boolean = false;

private var checkTimer:Timer = new Timer(1);
override public function Caret()
{
super();
createCaret();
}

private function createCaret():void{
draw();
checkTimer.addEventListener(TimerEvent.TIMER,checkTimer_handler);
checkTimer.start();
}


private function checkTimer_handler(event:TimerEvent):void{
var date:Date = new Date();
var elapsed:Number = (date.time-startTime.time)%PERIOD;
trace(elapsed);
if(elapsed>=(DELAY-DELTA) && elapsed<=DELAY){
this.graphics.clear();
trace("clear");
}
else if(elapsed>(PERIOD-DELTA) && elapsed<=PERIOD){
draw();
}
}

public function draw():void{
if(!started){
this.startTime = new Date();
started = true;
}
this.graphics.drawRect(10,30,2,20);
this.graphics.beginFill(0x000000);
trace("draw");
}
}
}


今天的研究结果表明,上述连续的Thread根本不可能保证,视代码而定。这部分内容属于高级内容。如有兴趣,请见http://www.bit-101.com/blog/?p=910。
阅读更多

没有更多推荐了,返回首页