想做一个,可以输入自定义item的textinput,研究了好几天,参考Adobe Masked TextInput http://www.adobe.com/cfusion/exchange/index.cfm?event=extensionDetail&extid=1049969#, 终于搞定了。
package UI{
import flash.display.DisplayObject;
import flash.events.Event;
import flash.events.FocusEvent;
import flash.events.KeyboardEvent;
import flash.events.MouseEvent;
import flash.events.TextEvent;
import flash.utils.Dictionary;
import mx.controls.TextInput;
import mx.core.IFlexDisplayObject;
import mx.core.IInvalidating;
import mx.core.mx_internal;
import mx.skins.ProgrammaticSkin;
import mx.styles.ISimpleStyleClient;
use namespace mx_internal;
[Style(name="CTextInputSkin", type="Class", inherit="no")]
public class CTextInput extends TextInput
{
private var mItemDict:Dictionary = new Dictionary();
public var mItemPosDict:Dictionary = new Dictionary();
private var mItemAttr:Dictionary = new Dictionary();
private var mKeyCode:int = -1;
private var mIsInItem:Boolean = false;
mx_internal var backgroundSkinName:String = "CTextInputSkin";
public function CTextInput()
{
super();
this.addEventListener(KeyboardEvent.KEY_DOWN, this_keyDown);
this.addEventListener(KeyboardEvent.KEY_UP, this_keyUp);
this.addEventListener("textChanged", this_textChanged);
this.addEventListener(TextEvent.TEXT_INPUT, this_textInput);
this.addEventListener(FocusEvent.FOCUS_IN, this_focusIn);
this.addEventListener(FocusEvent.FOCUS_OUT, this_focusOut);
this.addEventListener(MouseEvent.CLICK, this_mouseClick);
}
public function addItem(txt:String, attr:Object=null):void
{
if(txt != ""){
mItemPosDict[text.length] = txt.length; //加一个空格
//this.text = this.text + txt;
//htmlText = htmlText + "<font color=/"#00ff00/">" + txt + "</font><font color=/"#000000/"> </font>";
text = text + txt;
}
}
private function this_mouseClick(event:MouseEvent):void
{
var charIndex:int = textField.getCharIndexAtPoint(mouseX , mouseY);
if(this_isItem(charIndex)!= -1){
this.setSelection(text.length, text.length);
}
}
private function this_focusOut(event:Event):void
{
editable = true;
}
private function this_focusIn(event:FocusEvent):void
{
//var charIndex:int = textField.getCharIndexAtPoint(mouseX , mouseY);
if(this_isItem(textField.caretIndex)!= -1){
this.setSelection(text.length, text.length);
}
}
private function this_textInput(event:TextEvent):void
{
var index:int = textField.caretIndex==-1 ? text.length:textField.caretIndex;
this_changeItemPos(index, event.text.length);
}
private function this_keyUp(event:KeyboardEvent):void
{
if(event.keyCode == 8)
{
var index:int = textField.caretIndex+1;
var hit:int = this_hitItemBack(index);
//this_changeItemPos(textField.caretIndex, -1);
if(hit!=-1){
//this_changeItemPos(index, -mItemPosDict[hit]);
text = text.substr(0, hit) + text.substr(hit+mItemPosDict[hit]-1);
this_delItemPos(hit);
this_changeItemPos(index, -mItemPosDict[hit]);
}
}
else if(event.keyCode == 46)
{
var index:int = textField.caretIndex;
var hit:int = this_hitItemFront(index);
if(hit!=-1){
text = text.substr(0, hit) + text.substr(hit+mItemPosDict[hit]-1);
this_delItemPos(hit);
this_changeItemPos(index, -mItemPosDict[hit]);
}
}
}
private function this_keyDown(event:KeyboardEvent):void
{
//var charIndex:int = textField.getCharIndexAtPoint(mouseX , mouseY);
trace(event.keyCode);
var charIndex:int = 0;
if(event.keyCode == 37)
charIndex = textField.caretIndex==-1 ? (text.length-1) : (textField.caretIndex-1);
if(event.keyCode == 39)
charIndex = textField.caretIndex==-1 ? -1 : (textField.caretIndex+1);
if(this_isItem(charIndex)!= -1){
this.setSelection(textField.caretIndex, textField.caretIndex);
}
}
private function this_textChanged(event:Event):void{
}
private function this_delItemPos(pos:int):void{
delete mItemPosDict[pos];
}
private function this_changeItemPos(pos:int, chars:int):void{
var tmp:Dictionary = new Dictionary();
for(var prop:* in mItemPosDict){
if(pos <= int(prop)){
//mItemPosDict[prop+chars] = mItemPosDict[prop];
//delete mItemPosDict[prop];
tmp[prop+chars] = mItemPosDict[prop];
}
else{
tmp[prop] = mItemPosDict[prop];;
}
}
mItemPosDict = tmp;
}
private function this_hitItemBack(pos:int):int{
for(var prop:* in mItemPosDict){
if(pos == int(mItemPosDict[prop])+int(prop) )
return int(prop);
}
return -1;
}
private function this_hitItemFront(pos:int):int{
for(var prop:* in mItemPosDict){
if(pos == int(prop) )
return int(prop);
}
return -1;
}
private function this_isItem(pos:int):int{
for(var prop:* in mItemPosDict){
if(pos>int(prop) && pos<int(mItemPosDict[prop]+int(prop))){
return int(prop);
}
}
return -1;
}
override protected function updateDisplayList(w:Number, h:Number):void{
super.updateDisplayList(w,h);
createSkin();
}
private function createSkin():void
{
var skinName:String = backgroundSkinName;
// Has this skin already been created?
var newSkin:IFlexDisplayObject =
IFlexDisplayObject(getChildByName(skinName));
// If not, create it.
if (!newSkin)
{
var newSkinClass:Class = Class(getStyle(skinName));
if (!newSkinClass)
{
newSkinClass = CTextInputSkin;
}
if(newSkinClass)
{
newSkin = IFlexDisplayObject(new newSkinClass());
// Set its name so that we can find it in the future
// using getChildByName().
newSkin.name = skinName;
// Make the getStyle() calls in MTISkin find the styles
// for this control.
var styleableSkin:ISimpleStyleClient = newSkin as ISimpleStyleClient;
if (styleableSkin)
styleableSkin.styleName = this;
addChild(DisplayObject(newSkin));
// If the skin is programmatic, and we've already been
// initialized, update it now to avoid flicker.
if (newSkin is IInvalidating && initialized)
{
IInvalidating(newSkin).validateNow();
}
else if (newSkin is ProgrammaticSkin && initialized)
{
ProgrammaticSkin(newSkin).invalidateDisplayList();
}
}
}
// If the skin is already created then redraw it
// depending on the characters entered in the text input
else
{
ProgrammaticSkin(newSkin).invalidateDisplayList();
}
}
}
}
//用来显示item颜色的类
package UI
{
import flash.display.Graphics;
import flash.utils.Dictionary;
import mx.skins.ProgrammaticSkin;
public class CTextInputSkin extends ProgrammaticSkin
{
public function CTextInputSkin()
{
super();
}
override protected function updateDisplayList(w:Number, h:Number):void
{
super.updateDisplayList(w, h);
var fSize:Number = getStyle("fontSize");
var cellWidth:Number = 0;
var g:Graphics = this.graphics;
g.clear();
var cellColor:Number = getStyle("cellColor");
if(!cellColor)
{
cellColor = 0x00FF00;
}
g.lineStyle(0, 0xFFFFFF, 1);
var x1:Number = 0;
var y1:Number = 2;
switch(name)
{
case "CTextInputSkin":
if(parent is CTextInput)
{
g.beginFill(cellColor, 0.20);
var dict:Dictionary = CTextInput(parent).mItemPosDict;
for(var prop:* in dict)
{
var start:int = int(prop);
if(start == 0) x1 = 0;
else{
var txt:String = CTextInput(parent).text.substr(0, start);
x1 = CTextInput(parent).measureText(txt).width;
}
var item_txt:String = CTextInput(parent).text.substr(start, dict[prop]);
cellWidth = CTextInput(parent).measureText(item_txt).width;
var cellHeight:int = CTextInput(parent).measureText(item_txt).height;
g.drawRect(x1+3, y1,cellWidth,cellHeight+2);
}
g.endFill();
}
break;
}
}
}
}