actionscript 3 - Flex DataGrid row color spreads when scrolled up down -
i'm facing issue datagrid row background color being spread when datagrid vertically scrolled.
i'm assuming happening because itemrenderers recycled.
here's code :
<?xml version="1.0" encoding="utf-8"?> <mx:application xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical" minwidth="955" minheight="600" > <mx:script> <![cdata[ import mx.events.flexevent; private var rendererfactory:classfactory; protected function btn_clickhandler(event:mouseevent):void { setfilterwordinrenderer(); } protected function application1_creationcompletehandler(event:flexevent):void { setfilterwordinrenderer(); } private function setfilterwordinrenderer():void { if(!rendererfactory) rendererfactory = new classfactory(customitemrenderer) trace("reached setfilterwordinrenderer"); col1.itemrenderer = rendererfactory; col2.itemrenderer = rendererfactory; } ]]> </mx:script> <mx:button id="btn" label="highlight" click="btn_clickhandler(event)"/> <mx:datagrid id="dtg" width="378" height="496"> <mx:dataprovider> <mx:xmllist id="datxml" xmlns=""> <value id='test1'>abc</value> <value id='test2'>sadad</value> <value id='23'>ytuyt</value> <value id='24'>uytuty</value> <value id='62'>erewewwer</value> <value id='72'>tefcvsrwert</value> <value id='28'>uiiyui</value> <value id='82'>tryry</value> <value id='28'>iouoo</value> <value id='test1'>abc</value> <value id='test2'>sadad</value> <value id='23'>ytuyt</value> <value id='24'>uytuty</value> <value id='62'>erewewwer</value> <value id='72'>tefcvsrwert</value> <value id='28'>uiiyui</value> <value id='82'>tryry</value> <value id='28'>iouoo</value> <value id='test1'>abc</value> <value id='test2'>sadad</value> <value id='23'>ytuyt</value> <value id='24'>uytuty</value> <value id='62'>erewewwer</value> <value id='72'>tefcvsrwert</value> <value id='28'>uiiyui</value> <value id='82'>tryry</value> <value id='28'>iouoo</value> <value id='test1'>abc</value> <value id='test2'>sadad</value> <value id='23'>ytuyt</value> <value id='24'>uytuty</value> <value id='62'>erewewwer</value> <value id='72'>tefcvsrwert</value> <value id='28'>uiiyui</value> <value id='82'>tryry</value> <value id='28'>iouoo</value> </mx:xmllist> </mx:dataprovider> <mx:columns> <mx:datagridcolumn id="col1" headertext="col1" datafield="@id"/> <mx:datagridcolumn id="col2" headertext="col2" datafield="*"/> </mx:columns> </mx:datagrid> </mx:application> customitemrenderer.mxml
<?xml version="1.0" encoding="utf-8"?> <mx:hbox xmlns:mx="http://www.adobe.com/2006/mxml" implements="mx.controls.listclasses.idropinlistitemrenderer" > <mx:script> <![cdata[ import mx.collections.arraycollection; import mx.controls.datagrid; import mx.controls.label; import mx.controls.datagridclasses.datagridlistdata; import mx.controls.listclasses.baselistdata; private var mylabel:label; [bindable] private var _listdata:baselistdata; public function listdata() : baselistdata { return _listdata; } public function set listdata( value:baselistdata ) : void { _listdata = value; } override public function set data(value:object):void { if(!value) return; super.data = value; //set label text,using listdata , datafield make item renderer generic possible. if(this.mylabel == null) this.mylabel = new label(); this.mylabel.text = data[datagridlistdata(listdata).datafield]; this.addchild(this.mylabel); } override protected function updatedisplaylist(unscaledwidth:number, unscaledheight:number):void { super.updatedisplaylist(unscaledwidth, unscaledheight); var g:graphics = graphics; g.clear(); var object:object = _listdata; if (object.rowindex == 0) { //or whatever conditions g.beginfill(0xffffc0); g.drawrect(0, 0, unscaledwidth, unscaledheight); g.endfill(); } } ]]> </mx:script> </mx:hbox> the below snapshot correct when data loaded first time:

but when scroll through datagrid, below color applied random rows : 
you right. problem here itemrenderer recycle issue. here _listdata instance data match visible items many item become rowindex = 0 @ time of scrolling due recyle itemrenderer.
two ways can solve problem.
1) based on data (better value based highlight)
if (data.@rowno == "0") { //or rely on data way g.beginfill(0xffffc0); g.drawrect(0, 0, unscaledwidth, unscaledheight); g.endfill(); } but xml structure need add rowno attributes below
<value id='test1' rowno="0">abc</value> <value id='test2' rowno="1">sadad</value> <value id='23' rowno="2">ytuyt</value> 2) based on index (better index based highlight)
to grid dataprovider. griddataprovider = xmllistcollection((owner datagrid).dataprovider); in data setter method.
if (griddataprovider.getitemindex(data) == 0) { g.beginfill(0xffffc0); g.drawrect(0, 0, unscaledwidth, unscaledheight); g.endfill(); } below code have enough clarity (customitemrenderer.mxml).
<?xml version="1.0" encoding="utf-8"?> <mx:hbox xmlns:mx="http://www.adobe.com/2006/mxml" implements="mx.controls.listclasses.idropinlistitemrenderer"> <mx:script> <![cdata[ import mx.collections.xmllistcollection; import mx.controls.datagrid; import mx.controls.label; import mx.controls.datagridclasses.datagridlistdata; import mx.controls.listclasses.baselistdata; private var mylabel:label; [bindable] private var _listdata:baselistdata; [bindable] private var griddataprovider:xmllistcollection; public function listdata() : baselistdata { return _listdata; } public function set listdata( value:baselistdata ) : void { _listdata = value; } override protected function createchildren():void { super.createchildren(); this.mylabel = new label(); this.addchild(this.mylabel); } override public function set data(value:object):void { super.data = value; if(!value) return; //set label text,using listdata , datafield make item renderer generic possible. this.mylabel.text = data[datagridlistdata(listdata).datafield]; griddataprovider = xmllistcollection((owner datagrid).dataprovider); this.invalidatedisplaylist(); } override protected function updatedisplaylist(unscaledwidth:number, unscaledheight:number):void { super.updatedisplaylist(unscaledwidth, unscaledheight); var g:graphics = graphics; g.clear(); if (griddataprovider.getitemindex(data) == 0) { //or rely on data // if (data.@rowno == "0") { //or rely on data g.beginfill(0xffffc0); g.drawrect(0, 0, unscaledwidth, unscaledheight); g.endfill(); } } ]]> </mx:script> </mx:hbox> best practices: component creation goes createchildren() instead of data setter method.
Comments
Post a Comment