So I have created my first full custom component and would really like some 
feedback on it.  It replaces a List that uses ItemRenderers.  I hate the Flex 
List component, especially when using variableRowHeight and ItemRenderers.  I 
could never get it to work right, and the size changing scrollbar drove me 
nuts, so here is my ItemScroller component.  It is build fairly specific to the 
app I am building, but could be used elsewhere.  Basically it takes a 
dataprovider and ItemRenderer(Just another component really) and adds instances 
of the itemrender to a scrolling canvas contained in a VBox.  I added paging 
for really large datasets, and controls for that at the bottom.  So it would be 
really great to hear some suggestion on making this ItemScroller better, and 
feel free to use it if you want

So here is the code
<?xml version="1.0" encoding="utf-8"?>
<mx:VBox xmlns:mx="http://www.adobe.com/2006/mxml"; creationComplete="init()" 
horizontalScrollPolicy="off" horizontalGap="1" verticalGap="3" 
horizontalAlign="center">
<mx:Metadata>
        [Event(name="itemSelected", type="flash.events.Event")]
</mx:Metadata>
        <mx:Script>
                <![CDATA[
                        import mx.collections.ListCollectionView;
                        import mx.core.ScrollPolicy;
                        import mx.core.UIComponent;
                        import mx.core.Container;
                        import mx.collections.ICollectionView;
                        import mx.collections.XMLListCollection;
                        import mx.events.CollectionEvent;
                        import mx.collections.ArrayCollection;
                        
                        private var _dataProvider:ListCollectionView;
                        private var _pageData:ArrayCollection = new 
ArrayCollection();
                        private var _pageSize:int = 10;
                        [Bindable]private var _currPage:int = 1;
                        [Bindable]private var _numPages:Number;
                        [Inspectable]
                        public var selectable:Boolean = false;
                        public var selectedItem:Object;
                        
                        public var itemRenderer:Class;
                        private var isInit:Boolean = false;
                        
                        private function init():void
                        {       
                                isInit = true;
                                
                                if(_dataProvider != null){
                                        setDP();
                                        
                                }
                                
                        }
                        
                        override public function validateSize(recursive:Boolean 
= false):void {
                                super.validateSize(recursive);
                                if (!initialized) return;
                                if (itemCanvas.height < 
itemCanvas.measuredHeight) itemCanvas.verticalScrollPolicy = ScrollPolicy.ON;
                                else itemCanvas.verticalScrollPolicy = 
ScrollPolicy.OFF;
                        }
                        
                        public function set 
dataProvider(val:ListCollectionView):void
                        {
                                
                                if(val is XMLListCollection){
                                        //trace("set dp XMLListCollection");
                                        _dataProvider = val as 
XMLListCollection;
                                }else{
                                        //trace("set dp ArrayCollection");
                                        _dataProvider = val as ArrayCollection;
                                }
                                
_dataProvider.addEventListener(CollectionEvent.COLLECTION_CHANGE, setDP);
                                //_dataProvider.filterFunction = sortData;
                                setDP();
                                
                        }
                        
                        private function setDP(e:CollectionEvent = null):void
                        {
                                if(e != null){
                                        //trace("setDP event "+e.kind);
                                }
                                trace("dp length "+_dataProvider.length);
                                if(_dataProvider.length > 10){
                                        controls.visible = true;
                                        controls.height = 20;
                                        _numPages = numberOfPages();
                                        firstBtn.enabled = false;
                                        prevBtn.enabled = false;
                                        lastBtn.enabled = true;
                                        nextBtn.enabled = true;
                                        setPageData();
                                        //_dataProvider.refresh();
                                }else{
                                        controls.visible = false;
                                        controls.height = 0;
                                        _numPages = numberOfPages();
                                        _currPage = 1;
                                        createList(_dataProvider);
                                        
                                }
                        }
                        
                        private function createList(val:ListCollectionView):void
                        {
                                if(isInit){
                                        
                                        itemHolder.removeAllChildren();
                                        //trace("item dp "+_dataProvider);
                                        for each( var item:Object in val){
                                                
                                                var tmp:Container =  new 
itemRenderer() as Container;
                                                
                                                itemHolder.addChild(tmp);
                                                tmp.data = item;
                                                if(selectable){
                                                        
tmp.addEventListener(MouseEvent.CLICK, onItemClick);
                                                }
                                                
                                        }
                                }
                        }
                        
                        private function setPageData():void
                        {
                                var dataWindowCeiling:Number = _pageSize * 
_currPage;
                var dataWindowFloor:Number = dataWindowCeiling - _pageSize;
                                var pa:Array = _dataProvider.toArray();
                                pa = 
pa.slice(dataWindowFloor,dataWindowCeiling);
                                _pageData.source = pa;
                                createList(_pageData);
                        }
                        
                        private function controlClick(e:Event):void
                        {
                                //trace("control click");
                                itemCanvas.verticalScrollPosition = 0;
                                if(e.currentTarget.label == "prev"){
                                        if(_currPage > 1){
                                                _currPage --;
                                                //_dataProvider.refresh();
                                                //createList();
                                                lastBtn.enabled = true;
                                                nextBtn.enabled = true;
                                                if(_currPage == 1){
                                                        firstBtn.enabled = 
false;
                                                        prevBtn.enabled = false;
                                                }
                                                setPageData();
                                        }
                                }else if(e.currentTarget.label == "next"){
                                        if(_currPage < _numPages){
                                                _currPage ++;
                                                //_dataProvider.refresh();
                                                //createList();
                                                firstBtn.enabled = true;
                                                prevBtn.enabled = true;
                                                if(_currPage == _numPages){
                                                        lastBtn.enabled = false;
                                                        nextBtn.enabled = false;
                                                }
                                                setPageData();
                                        }
                                }else if(e.currentTarget.label == "first"){
                                        if(_currPage > 1){
                                                _currPage  = 1;
                                                //_dataProvider.refresh();
                                                //createList();
                                                firstBtn.enabled = false;
                                                prevBtn.enabled = false;
                                                lastBtn.enabled = true;
                                                nextBtn.enabled = true;
                                                setPageData();
                                        }
                                }else if(e.currentTarget.label == "last"){
                                        if(_currPage < _numPages){
                                                _currPage  = _numPages;
                                                //_dataProvider.refresh();
                                                //createList();
                                                lastBtn.enabled = false;
                                                nextBtn.enabled = false;
                                                firstBtn.enabled = true;
                                                prevBtn.enabled = true;
                                                setPageData();
                                        }
                                }
                        }
                        
                        public function numberOfPages() : Number
                {
                        var result:Number = _dataProvider.length / _pageSize;
                        result = Math.ceil( result );
                return result;
                }
                
                private function onItemClick(e:MouseEvent):void
                {
                        //trace(e.currentTarget.data.elementID);
                        selectedItem = e.currentTarget.data;
                        dispatchEvent(new Event("itemSelected"));
                }
                ]]>
        </mx:Script>
        
                <mx:Canvas id="itemCanvas" width="100%" height="100%" 
verticalPageScrollSize="10" horizontalScrollPolicy="off" borderStyle="solid">
                        <mx:VBox id="itemHolder" width="100%" height="100%" 
paddingBottom="4" paddingLeft="4" paddingRight="4" paddingTop="4"/>
                </mx:Canvas>
                <mx:HBox id="controls" verticalAlign="middle" visible="false" 
height="0" backgroundColor="#FFFFFF" backgroundAlpha="0.5" paddingLeft="10" 
paddingRight="10" borderStyle="solid">
                        <mx:LinkButton id="firstBtn" label="first" height="20" 
click="controlClick(event)" enabled="false"/>
                        <mx:LinkButton id="prevBtn" label="prev" height="20" 
click="controlClick(event)" enabled="false"/>
                        <mx:Label text="{_currPage} of {_numPages}" width="38"/>
                        <mx:LinkButton id="nextBtn" label="next" height="20" 
click="controlClick(event)"/>
                        <mx:LinkButton id="lastBtn" label="last" height="20" 
click="controlClick(event)"/>
                </mx:HBox>
        
        
</mx:VBox>


and here is the implementation
<ItemScroller width="100%" height="100%" itemRenderer="{Component}" 
id="historyList" dataProvider="{ListCollectionView}" selectable="true" 
itemSelected="function(event);/>

thanks
Russ


Reply via email to