📄 customlist.mxml
字号:
<?xml version="1.0" encoding="utf-8"?>
<mx:List xmlns:mx="http://www.adobe.com/2006/mxml"
creationComplete="handleCreationComplete(event)"
>
<!--
Author: Mike Martin
Version: 1.0.1
Date: 2008/01/01
Contact: mike@teknision.com
Description: A custom list class that should make the list component easier to work with.
1. drawAll - If set to true will not re-use itemrenderers (ads some processing time)
2. useDefaultIndicators - Will turn off default rollover and selection skins
3. getItemByNumber() - Will return the itemrenderer instance for a specific number within that array
Tags: list, custom, easy, itemrenderer
Contributors:
-->
<mx:Metadata>
[Event(name="collectionChange", type="mx.events.CollectionEvent")]
</mx:Metadata>
<mx:Script>
<![CDATA[
import mx.utils.UIDUtil;
import mx.binding.utils.*;
import mx.events.*;
import mx.controls.listClasses.IListItemRenderer;
import mx.collections.*;
////////////////////////////////////////
// PUBLIC VARIABLES
[Bindable]
public var items:ArrayCollection = new ArrayCollection();
public var drawAll:Boolean = true;
////////////////////////////////////////
// PRIVATE VARIABLES
private var __useDefaultIndicators:Boolean = true;
private var __supposedlySelectedItems:Array = new Array();
private var __dataProvider:Object;
////////////////////////////////////////
// PUBLIC SETTERS / GETTERS
override public function set dataProvider(i_data:Object):void
{
super.dataProvider = i_data;
this.callLater(addItemsToItems,[i_data]);
}
public function set useDefaultIndicators(i_use:Boolean):void{
__useDefaultIndicators = i_use;
this.callLater(alterSelectionLayerVisibility,[i_use]);
}
public function get useDefaultIndicators():Boolean{
return __useDefaultIndicators;
}
////////////////////////////////////////
// PUBLIC METHODS
// RETURN AN ITEM RENDERER BY NUMBER
public function getItemByNumber(i_num:uint):Object{
try
{
var dataItem:Object = dataProvider[i_num];
return this.itemToItemRenderer(dataItem);
}catch(error:Error)
{
trace("ERROR : "+this+" : "+error);
}
return null;
}
////////////////////////////////////////
// OVERRIDING METHODS
override protected function drawSelectionIndicator(indicator:Sprite, xx:Number, yy:Number,ignoredWidth:Number, h:Number, color:uint,ignoredRenderer:IListItemRenderer):void
{
// CALL A METHOD IN THE ITEM RENDERER CALLED 'handleItemSelected'
this.callFunctionInRenderer(ignoredRenderer,"handleItemSelected");
super.drawSelectionIndicator(indicator,xx,yy,ignoredWidth,h,color,ignoredRenderer);
this.adjustForMultipleSelectionError(ignoredRenderer);
}
override protected function drawHighlightIndicator(indicator:Sprite, xx:Number, yy:Number,ignoredWidth:Number, h:Number, color:uint,ignoredRenderer:IListItemRenderer):void
{
// CALL A METHOD IN THE ITEM RENDERER CALLED 'handleItemHighlighted'
this.callFunctionInRenderer(ignoredRenderer,"handleItemHighlighted");
super.drawHighlightIndicator(indicator,xx,yy,ignoredWidth,h,color,ignoredRenderer);
}
override protected function clearHighlightIndicator(indicator:Sprite,
itemRenderer:IListItemRenderer):void
{
// CALL A METHOD IN THE ITEM RENDERER CALLED 'handleClearItemHighlighted'
this.callFunctionInRenderer(itemRenderer,"handleClearItemHighlighted");
}
// LOOPS OVER THE SELECTED ITEMS AND CALLS THE 'handleClearItemSelected' METHOD
// ON THOSE ITEM RENDERERS. THERE IS AN ISSUE WITH THIS AND MULTIPLE SELECTIONS.
override protected function clearSelected(transition:Boolean = false):void
{
for (var uniqueID:String in selectedData)
{
var data:Object = selectedData[uniqueID].data;
var item:IListItemRenderer = UIDToItemRenderer(itemToUID(data));
this.callFunctionInRenderer(item,"handleClearItemSelected");
super.clearSelected(transition);
var itemIndex:Number = this.__supposedlySelectedItems.indexOf(item);
if(itemIndex > -1)
{
this.__supposedlySelectedItems.splice(itemIndex,1);
}
}
}
// IF 'drawAll' IS SET TO true THEN MAKE THE LIST LOOK LIKE IT HAS A HEIGHT OF 2000
// AS IT DRAWS THE ITEM RENDERERS. THIS PREVENTS MORE THAN ONE ITEM RENDERER FROM BEING
// USED MORE THAN ONCE.
override protected function makeRowsAndColumns(left:Number, top:Number,
right:Number, bottom:Number,
firstCol:int, firstRow:int,
byCount:Boolean = false, rowsNeeded:uint = 0):Point
{
if(drawAll)
{
bottom = 200000;
}
var point:Point = super.makeRowsAndColumns(left, top, right, bottom, firstCol, firstRow, false, 0);
return point;
}
////////////////////////////////////////
// PRIVATE METHODS
private function handleCreationComplete(event:Event):void
{
// ADDED A COLLECTIONCHANGE LISTENER WHICH IS PICKED UP BY ARRAY COLLECTIONS
super.dataProvider.removeEventListener(CollectionEvent.COLLECTION_CHANGE,handleCollectionChange);
super.dataProvider.addEventListener(CollectionEvent.COLLECTION_CHANGE,handleCollectionChange);
}
// ADD ITEM RENDERERS TO THE ITEMS ARRAY
private function addItemsToItems(i_data:Object):void
{
if(i_data != null)
{
items = new ArrayCollection();
for(var i:uint=0;i<i_data.length;i++)
{
var item:IListItemRenderer = this.itemToItemRenderer(i_data[i]);
items.addItem(item);
}
this.fireCollectionChangeEvent(i_data);
}
}
// WHENEVER A DATAPROVIDER CHANGES COMPLETELY FIRE OFF THE COLLECTION CHANGE EVENT
private function fireCollectionChangeEvent(i_data:Object):void{
var tempArray:Array = new Array();
for(var i:uint=0;i<i_data.length;i++)
{
tempArray.push(i_data[i]);
}
var tempCollectionEvent:CollectionEvent = new CollectionEvent(CollectionEvent.COLLECTION_CHANGE);
tempCollectionEvent.items = tempArray;
tempCollectionEvent.kind = CollectionEventKind.ADD;
tempCollectionEvent.oldLocation = -1;
tempCollectionEvent.location = -1;
this.dispatchEvent(tempCollectionEvent);
}
private function handleCollectionChange(event:CollectionEvent):void
{
this.callLater(handleCollectionChangeAfter,[event]);
}
// WITH AN ARRAY COLLECTION THIS METHOD ADDS THE APPROPRIATE ITEM TO THE ITEMS ARRAY
// AND DISPATCHES A COLLECTION CHANGE EVENT
private function handleCollectionChangeAfter(event:CollectionEvent):void
{
try
{
var item:Object = this.itemToItemRenderer(dataProvider[event.location]);
var newObject:Object = new Object();
newObject.data = item;
newObject.UID = event.location;
if(event.kind == CollectionEventKind.ADD)
{
items.addItemAt(item,event.location);
}else if(event.kind == CollectionEventKind.REMOVE)
{
items.removeItemAt(event.location);
}else if(event.kind == CollectionEventKind.MOVE)
{
try
{
items.removeItemAt(event.oldLocation);
}catch(error:Error){
trace("MOVE ERROR : "+this+" : "+error);
}
items.addItemAt(item,event.location);
}else if(event.kind == CollectionEventKind.REPLACE)
{
items.setItemAt(item,event.location);
}
}catch(error:Error){
trace("ERROR : "+this+" : "+error);
}
this.dispatchEvent(event);
}
// CALLS VARIOUS FUNCTIONS ON THE LIST'S ITEM RENDERER
// THROWS TRACE ERROR IF IT CAN'T FIND THE FUNCTION
private function callFunctionInRenderer(i_renderer:Object,functionStr:String):void
{
try{
// Needed to convert the itemrenderer to an object so it doesn't throw an error
// when the functionStr gets called and isn't there.
var rendererClass:Object = new Object();
rendererClass = i_renderer as Object;
rendererClass[functionStr]();
}catch(error:Error){
trace("CUSTOM LIST : Item Doesn't have "+functionStr+" function on "+i_renderer);
}
}
// DIDN'T ALWAYS CALL THE CLEAR ITEM SELECT FUNCTION ON ITEM RENDERER, SO DID
// ADDITIONAL CHECK TO FIND THE RENDERERS THAT AREN'T SELECTED
private function adjustForMultipleSelectionError(i_itemRenderer:IListItemRenderer):void{
var indexOf:Number = this.__supposedlySelectedItems.indexOf(i_itemRenderer);
if(indexOf == -1)
{
this.__supposedlySelectedItems.push(i_itemRenderer);
}
var crapArray:Array = this.__supposedlySelectedItems.filter(checkToSeeIfItsASelectedItem);
crapArray.forEach(removeItemFromTempList);
}
// MAKES THE CHECK TO SEE IF THE ITEMS THAT OUR ARRAY (__supposedlySelectedItems)
// ARE ACTUALLY SELECTED AND IF THEY'RE NOT THEN CALL THE 'handleClearItemSelected'
// METHOD ON THE ITEM RENDERER
private function checkToSeeIfItsASelectedItem(i_obj:Object,x:Number,y:Number):Boolean{
for(var i:uint = 0;i<this.selectedIndices.length;i++)
{
if(this.getItemByNumber(this.selectedIndices[i]) == i_obj)
{
return false;
}
}
return true;
}
private function removeItemFromTempList(i_obj:Object,x:Number,y:Number):void{
this.callFunctionInRenderer(i_obj,"handleClearItemSelected");
var indexOf:Number = this.__supposedlySelectedItems.indexOf(i_obj);
this.__supposedlySelectedItems.splice(indexOf,1);
}
private function alterSelectionLayerVisibility(i_vis:Boolean){
this.selectionLayer.visible = i_vis;
}
]]>
</mx:Script>
</mx:List>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -