自己写了一个不是太完美的自带下拉查询功能结果的textinput
先看看,运行截图:
一共三个类:自定义的textinput类,自定义event类,外部调用类
自定义的textinput类:
package components
{
import flash.events.Event;
import flash.events.KeyboardEvent;
import flash.events.MouseEvent;
import flash.geom.Point;
import flash.ui.Keyboard;
import mx.collections.ArrayCollection;
import mx.controls.Button;
import mx.controls.List;
import mx.controls.TextInput;
import mx.core.ScrollPolicy;
import mx.core.UIComponent;
import mx.events.FlexEvent;
import mx.events.FlexMouseEvent;
import mx.events.ListEvent;
import mx.managers.PopUpManager;
import mx.utils.StringUtil;
[Event(name="textChange", type="flash.events.Event")]
[Event(name="itemSelected", type="components.SearchBoxEvent")]
public class SearchBox extends UIComponent
{
[Embed("assets/icon_close.png")]
private var closeIcon:Class;
private var textInput:TextInput;
private var closeButton:Button;
private var list:List;
private var isListVisible:Boolean = false;
private var _dataProvider:Object;
private var _text:String;
private var _labelField:String = "label";
private function searchName(item:Object):Boolean
{
var str:String = StringUtil.trim(text);
str = str.toLowerCase();
if(str==''){
return true;
}
return item.toLowerCase().search(str) != -1;
}
private function textChangeHandler():void
{
if(this.dataProvider!=null){
this.dataProvider.filterFunction = searchName;
this.dataProvider.refresh();
showOrHide();
}
}
private function showOrHide():void{
if (dataProvider != null && dataProvider.length > 0){
if (!isListVisible) {
popup();
}
list.selectedIndex = 0;
}else{
if (isListVisible) {
removePopup();
}
}
}
override protected function createChildren():void
{
super.createChildren();
textInput = new TextInput();
textInput.addEventListener(Event.CHANGE, textInput_changeHandler);
textInput.addEventListener(KeyboardEvent.KEY_DOWN, textInput_keyDownHandler);
addChild(textInput);
closeButton = new Button();
closeButton.setStyle("icon", closeIcon)
closeButton.setStyle("skin", null)
closeButton.addEventListener(MouseEvent.CLICK, closeHandler);
closeButton.width = 20;
addChild(closeButton);
list = new List();
if(labelField!=null&&labelField!=''){
list.labelField = labelField;
}
list.showScrollTips = true;
list.showDataTips = true;
list.dataProvider = dataProvider;
list.setStyle("dropShadowEnabled", true);
list.addEventListener(ListEvent.ITEM_CLICK, selectItem);
showOrHide();
systemManager.addEventListener(Event.RESIZE, removePopup, false, 0, true);
}
override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void
{
super.updateDisplayList(unscaledWidth, unscaledHeight);
textInput.width = unscaledWidth - closeButton.width;
textInput.height = unscaledHeight;
closeButton.height = unscaledHeight;
closeButton.move(unscaledWidth - closeButton.width, 0);
}
override protected function measure():void
{
super.measure();
this.measuredWidth = 160;
this.measuredHeight = textInput.measuredHeight;
}
private function textInput_keyDownHandler(event:KeyboardEvent):void
{
switch (event.keyCode)
{
case Keyboard.DOWN:
if (isListVisible){
list.selectedIndex++;// list update selectedItem
list.scrollToIndex(list.selectedIndex);
}
else{
popup();
}
textInput.setSelection(0, textInput.text.length);
break;
case Keyboard.UP:
if (isListVisible && list.selectedIndex > 0)
{
list.selectedIndex--; // list update selectedItem
list.scrollToIndex(list.selectedIndex);
}
textInput.setSelection(0, textInput.text.length);
//textInput.setSelection(textInput.text.length, textInput.text.length); // select nothing
break;
case Keyboard.ENTER:
if (isListVisible) selectItem();
break;
case Keyboard.ESCAPE:
if (isListVisible) removePopup();
break;
}
}
private function textInput_changeHandler(event:Event):void
{
text = textInput.text;
textChangeHandler();
// for external event listener
dispatchEvent(new Event("textChange"));
}
private function list_mouseDownOutsideHandler(event:MouseEvent):void
{
removePopup();
}
private function selectItem(event:ListEvent = null):void
{
var obj:Object = list.selectedItem;
if(obj.hasOwnProperty(labelField)){
textInput.text = obj[labelField];
}else{
textInput.text = list.selectedItem.toString();
}
text = textInput.text;
dispatchEvent(new SearchBoxEvent(SearchBoxEvent.ITEM_SELECTED, list.selectedItem));
removePopup();
}
public function get selectedItem():Object{
if(list==null){
return null;
}
return list.selectedItem;
}
private function popup():void
{
PopUpManager.addPopUp(list, this);
isListVisible = true;
list.width = textInput.width;
var point:Point = new Point(0, unscaledHeight);
point = localToGlobal(point);
point = list.parent.globalToLocal(point);
list.move(point.x, point.y);
list.addEventListener(FlexMouseEvent.MOUSE_DOWN_OUTSIDE, list_mouseDownOutsideHandler);
}
private function removePopup(event:Event=null):void
{
PopUpManager.removePopUp(list);
list.removeEventListener(FlexMouseEvent.MOUSE_DOWN_OUTSIDE, list_mouseDownOutsideHandler);
isListVisible = false;
}
private function closeHandler(event:MouseEvent):void
{
textInput.text = "";
text = "";
textChangeHandler();
dispatchEvent(new Event("textChange"));
textInput.setFocus();
}
public function get dataProvider():Object
{
return _dataProvider;
}
public function set dataProvider(dp:Object):void
{
_dataProvider = dp;
}
public function get text():String
{
return _text;
}
public function set text(value:String):void
{
_text = value;
}
public function get labelField():String
{
return _labelField;
}
public function set labelField(value:String):void
{
_labelField = value;
}
}
}
自定义event类:
package components
{
import flash.events.Event;
public class SearchBoxEvent extends Event
{
public static const ITEM_SELECTED:String = "itemSelected";
public var item:Object;
public function SearchBoxEvent(type:String, item:Object, bubbles:Boolean = true, cancelable:Boolean = false)
{
this.item = item;
super(type, bubbles, cancelable);
}
}
}
外部调用类:
<?xml version="1.0" encoding="utf-8"?>
<s:WindowedApplication xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx" xmlns:components="components.*">
<fx:Style>
@namespace s "library://ns.adobe.com/flex/spark";
@namespace mx "library://ns.adobe.com/flex/mx";
@namespace local "*";
s|Label {
color: #000000;
}
</fx:Style>
<fx:Script>
<![CDATA[
import components.SearchBoxEvent;
import mx.collections.ArrayCollection;
import mx.controls.Alert;
[Bindable]
private var names:ArrayCollection = new ArrayCollection([
{label:"你 好"},
{label:"好 好"},
{label:"你1234567897897897897489789789好"},
{label:"我好,你好我好,你好"},
{label:"好好好你我好,你好"},
{label:"我好"},
{label:"我好22"},
{label:"我好11"},
{label:"我好abcdefcgadsfasdfsdfasdfasdf12345678979999999999999999999"},
{label:"我好1"},
{label:"我好2"},
{label:"我好3"},
{label:"我好4"},
{label:"我好5"},
{label:"我好6"},
{label:"我好7"},
{label:"我好8"},
{label:"我好9"}
]);
private function itemSelectedHandler(event:SearchBoxEvent):void
{
fullName.text = event.item as String;
var ba:ByteArray = new ByteArray();
ba.writeMultiByte(fullName.text,"gbk");
Alert.show((ba.length).toString());
// Alert.show((getStrActualLen(fullName.text)).toString());
}
private function getStrActualLen(sChars:String) : int {
return sChars.replace(/[^\x00-\xff]/g,"xx").length;
}
]]>
</fx:Script>
<s:Panel title="Components Samples" width="100%" height="100%">
<s:layout>
<s:HorizontalLayout paddingLeft="10" paddingRight="10" paddingTop="10" paddingBottom="10"/>
</s:layout>
<s:HGroup >
<mx:List dataProvider="{names}" width="140" showScrollTips="true" showDataTips="true">
</mx:List>
<s:Label text="Type a few characters to search:" />
<components:SearchBox id="searchBox" dataProvider="{names}" itemSelected="itemSelectedHandler(event)"/>
</s:HGroup>
<mx:FormItem label="You selected:" >
<s:TextInput id="fullName"/>
</mx:FormItem>
</s:Panel>
</s:WindowedApplication>