4 Replies Latest reply on May 3, 2010 12:47 PM by flairjax

    Flex custom List itemRenderer skin not updating with data

    flairjax Level 1

      I have a custom List component with a custom ItemRenderer and when I sort the list the itemRenderers are not updating.  After your sort the list the skins stay the same, but if you then mouse over the items in the list then the skins update to show the new data behind the renderer.  Its like invalidate isn't happening or something?

       

      I have tried all the old invalidateLayout, invalidateSize, etc... but those don't work. Is there a new invalidate??? in Flex 4 I should be using or one for the itemRenderers?

       

      TIA, J

        • 1. Re: Flex custom List itemRenderer skin not updating with data
          Shongrunden Adobe Employee

          Are you using an itemRendererFunction?

           

          Does this hapen when you set useVirtualLayout="false" on the List?

          • 2. Re: Flex custom List itemRenderer skin not updating with data
            flairjax Level 1

            Not using the itemRendererFunction.  And yes still happening when I set the useVirtualLayout == false.

            • 3. Re: Flex custom List itemRenderer skin not updating with data
              Shongrunden Adobe Employee

              Are you using a TileLayout in your List?

               

              Any chance you could post a simplified example that demonstrates the bug so we can investigate further?

              • 4. Re: Flex custom List itemRenderer skin not updating with data
                flairjax Level 1

                Here is my component code.  If I use itemRendererFunction and set useVirtualLayout="false" the problem goes away but then my list which contains 1000 heavy UI itermRenderers makes my app really really slow.

                 

                 

                 

                package com.myapp.view.components
                {
                    import  assets.style.skins.buttonbar.PlainButtonBarSkin;
                   
                    import  flash.events.MouseEvent;
                   
                    import  mx.collections.ICollectionView;
                    import mx.collections.Sort;
                     import mx.collections.SortField;
                    import  mx.events.StateChangeEvent;
                    import mx.utils.ObjectUtil;
                   
                     import spark.components.ButtonBar;
                    import spark.components.List;
                    
                    [SkinState("halfOpened")];
                    [SkinState("fullyOpened")];
                     [SkinState("collapsed")];
                    public class CollapsibleSortableList  extends List
                    {
                        protected var _collapsed:Boolean =  false;
                        protected var _halfOpened:Boolean = true;
                         protected var _fullyOpened:Boolean = false;
                       
                         //Declare the additional SkinStates
                         [SkinPart(required="false")]
                        public var  sortButtonBar:ButtonBar;
                       
                         /*[SkinPart(required="true")]
                        public var header:Button;*/
                        
                        private const SORT_ASCENDING:int = 0;
                       
                         private const SORT_DESCENDING:int = 1;
                       
                        private  var _sorting:int = SORT_DESCENDING;
                       
                        private var  _sort:Sort;
                       
                        private var _sortField:String =  'name';
                       
                        private var _dataSortField:SortField;
                         private var _numericDataSort:Sort;
                        private var  _alphaSort:Sort;
                        private var _dp:ICollectionView;
                       
                         public function CollapsibleSortableList()
                        {
                             super();
                        }
                       
                       
                        //Add  Event-Listeners to the textview for FocusEvent
                        override  protected function partAdded(partName:String, instance:Object):void {
                             super.partAdded(partName, instance);
                            if (instance ==  sortButtonBar) {
                                trace ("Adding sort button");
                                 ButtonBar(instance).setStyle( 'skinClass',  assets.style.skins.buttonbar.PlainButtonBarSkin );
                                 ButtonBar(instance).addEventListener( MouseEvent.CLICK,  sortButtonBar_changeHandler);
                            }
                        }
                       
                         //Clean up Event-Listeners and stuff...
                        override protected  function partRemoved(partName:String, instance:Object):void {
                             super.partRemoved(partName, instance);
                            if (instance ==  sortButtonBar) {
                                trace ("Removing sort button");
                                 ButtonBar(instance).removeEventListener(MouseEvent.CLICK,  sortButtonBar_changeHandler);
                            }
                        }
                       
                         private function convertIPToInteger( val:Object ) : Number
                        {
                             var num:Number = 0;
                            var pattern:RegExp =  /([0-9]+)\.([0-9]+)\.([0-9]+)\.([0-9]+)/;
                           
                             if(val && val.ip != null){
                                var str:String =  val.ip;
                                trace(pattern.exec(str));
                                 var o:* = pattern.exec(str);
                            }
                            if( o ==  null ) { return num };
                            var p1:Number = parseInt(o[1]) *  16777216;
                            var p2:Number = parseInt(o[2]) * 65536;
                             var p3:Number = parseInt(o[3]) * 256;
                            var p4:Number =  parseInt(o[4]) * 1;
                            num = p1 + p2 + p3 + p4;
                            
                            return num;
                        }
                       
                        private  function convertNetworkToInteger( val:Object ) : Number
                        {
                             var num:Number = 0;
                            var pattern:RegExp =  /([0-9]+)\.([0-9]+)\.([0-9]+)\.([0-9]+)\/([0-9]+)/;
                           
                             if(val && val.network != null){
                                var  str:String = val.cloud;
                                trace(pattern.exec(str));
                                 var o:* = pattern.exec(str);
                            }
                            if( o ==  null ) { return num };
                            var p1:Number = parseInt(o[1]) *  4294967296;
                            var p2:Number = parseInt(o[2]) * 16777216;
                             var p3:Number = parseInt(o[3]) * 65536;
                            var p4:Number =  parseInt(o[4]) * 256;
                            var p5:Number = parseInt(0[5]) * 1
                             num = p1 + p2 + p3 + p4 + p5;
                           
                            return  num;
                        }
                       
                        private function  ip_compareFunc( itemA:Object, itemB:Object ) : int
                        {
                             var valueA:Number = convertIPToInteger( itemA );
                            var  valueB:Number = convertIPToInteger( itemB );
                            return  ObjectUtil.numericCompare( valueA, valueB );
                        }
                       
                         private function network_compareFunc( itemA:Object, itemB:Object ) :  int
                        {
                            var valueA:Number =  convertNetworkToInteger( itemA );
                            var valueB:Number =  convertNetworkToInteger( itemB );
                            if( itemA == itemB ) {
                                 if( itemA.type == 'cloud' ){
                                    return 1;
                                 }else if( itemB.type == 'cloud' ) {
                                    return -1;
                                 }
                            }
                            return ObjectUtil.numericCompare(  valueA, valueB );
                        }

                 

                       
                        protected function  sortButtonBar_changeHandler(event:*):void
                        {
                             var str:String = event.target.label as String;
                            str =  str.toLowerCase();
                            this._sortField = str;
                             //sortList();
                           
                            /* Create the SortField  object for the correct field in the ArrayCollection object  */
                             _dataSortField = new SortField();
                            _dataSortField.name =  _sortField;
                           
                            if( str == 'name' ){
                                 doAlphaSort();
                            }else if( str == 'ip' ){
                                 _dataSortField.compareFunction = ip_compareFunc;
                                 doSpecialSort();
                            }else{
                                 _dataSortField.compareFunction = network_compareFunc;
                                 doSpecialSort();
                            }
                        }
                       
                         private function doAlphaSort() : void
                        {
                            _dp =  this.dataProvider as ICollectionView;
                           
                            /*  Create the Sort object and add the SortField object created earlier to  the array of fields to sort on. */
                            _alphaSort = new  Sort();
                            _alphaSort.fields = [_dataSortField];
                            
                            /* Set the ArrayCollection object's sort property to  our custom sort, and refresh the ArrayCollection. */
                            if  (_dp != null)
                            {
                                if (this._sorting ==  SORT_ASCENDING)
                                {
                                     this._alphaSort.reverse();
                                    this._sorting =  SORT_DESCENDING;
                                }
                                else
                                 {
                                    this._sorting = SORT_ASCENDING;
                                 }
                               
                                _dp.sort = this._alphaSort;
                                 _dp.refresh();
                            }
                        }
                       
                         private function doNumericSort() : void
                        {
                            _dp =  this.dataProvider as ICollectionView;
                             _dataSortField.numeric = true;
                           
                            /* Create  the Sort object and add the SortField object created earlier to the  array of fields to sort on. */
                            _numericDataSort = new  Sort();
                            _numericDataSort.fields = [_dataSortField];
                            
                            /* Set the ArrayCollection object's sort property to  our custom sort, and refresh the ArrayCollection. */
                            if  (_dp != null)
                            {
                                if (this._sorting ==  SORT_ASCENDING)
                                {
                                     this._numericDataSort.reverse();
                                    this._sorting =  SORT_DESCENDING;
                                }
                                else
                                 {
                                    this._sorting = SORT_ASCENDING;
                                 }
                               
                                _dp.sort =  this._numericDataSort;
                                _dp.refresh();
                            }
                         }
                       
                        private function doSpecialSort() : void
                         {
                            _dp = this.dataProvider as ICollectionView;
                            
                            /* Create the Sort object and add the SortField object  created earlier to the array of fields to sort on. */
                             _numericDataSort = new Sort();
                            _numericDataSort.fields =  [_dataSortField];
                           
                            /* Set the  ArrayCollection object's sort property to our custom sort, and refresh  the ArrayCollection. */
                            if (_dp != null)
                            {
                                 if (this._sorting == SORT_ASCENDING)
                                {
                                     this._numericDataSort.reverse();
                                    this._sorting =  SORT_DESCENDING;
                                }
                                else
                                 {
                                    this._sorting = SORT_ASCENDING;
                                 }
                               
                                _dp.sort =  this._numericDataSort;
                                _dp.refresh();
                            }
                         }
                       
                       
                        private function sortList():void
                         {
                            var dp:ICollectionView = this.dataProvider as  ICollectionView;
                            this._sort = new Sort();
                             this._sort.fields = [new SortField(this._sortField)];
                           
                             if (dp != null)
                            {
                                if (this._sorting  == SORT_ASCENDING)
                                {
                                     this._sort.reverse();
                                    this._sorting =  SORT_DESCENDING;
                                }
                                else
                                 {
                                    this._sorting = SORT_ASCENDING;
                                 }
                               
                                dp.sort = this._sort;
                                 dp.refresh();
                            }
                        }
                       
                         //Gets called after invalidateSkinState() by Flex
                        override  protected function getCurrentSkinState():String {
                            if  (_collapsed) {
                                this.dispatchEvent(new  StateChangeEvent( StateChangeEvent.CURRENT_STATE_CHANGING, false, false,  null, 'collapsed' ) );
                                return "collapsed";
                             }else if( _halfOpened ){
                                this.dispatchEvent(new  StateChangeEvent( StateChangeEvent.CURRENT_STATE_CHANGING, false, false,  null, 'halfOpened' ) );
                                return "halfOpened";
                             }else if( _fullyOpened ) {
                                this.dispatchEvent(new  StateChangeEvent( StateChangeEvent.CURRENT_STATE_CHANGING, false, false,  null, 'fullyOpened' ) );
                                return "fullyOpened";
                             }else{
                                return super.getCurrentSkinState();
                             }
                        }

                 

                       
                       
                    }
                }