flash - How do I implement a infinite list in Flex (hero) -
i'm new flex/actionscript (.net/java has been main playground far). i'm trying build flex app has list meant , behave infinite list (of items - can object). idea user should able scroll or down , never reach end of list in either direction.
an example list of numbers. scrolling show negative numbers; scrolling down show positive ones. now, list simple flex spark list (using flex hero). bound data provider arraylist.
my initial idea listen scroll event , add/remove items needed. however, in current build of flex hero, there bug doesn't raise scroll events vertical scrollbars (http://bugs.adobe.com/jira/browse/sdk-26533).
so, i'm using workaround suggested in link above (i.e listening propertychanged event of list's scroller's viewport. event though gives me current verticalscrollposition.
and looks default spark list supports smooth scrolling , raises event many times before list scrolling comes standstill (it nice visual effect).
now, need :
- figure out whether scrolling or down (how do that?)
figure out items visible. can from:
list.datagroup.getitemindicesinview()add/remove items needed, user can scroll , down forever, never reaching end of list in either direction.
i've tried following code doesn't work. (comments in code).
any flex experts out there? please help.
import mx.collections.arraylist; import mx.core.inavigatorcontent; import mx.events.flexevent; import mx.events.propertychangeevent; var listdata:arraylist; var firstiteminview:int = 0; var lastiteminview:int = 0; var count = 0; //gets visible item indices (first , last) private function getvisibleindices():vector.<int> { var ind:vector.<int> = new vector.<int>(2, true); ind[0] = firstiteminview; ind[1] = lastiteminview; return ind; } protected function view_creationcompletehandler(event:flexevent):void { //create initialise list data listdata = new arraylist(); for(var i:int = 0; < 6; i++){ listdata.additemat(i, i); } infinitelist.dataprovider = listdata; updateindices(); infinitelist.scroller.viewport.addeventlistener(propertychangeevent.property_change, infinitelist_verticalscroll_propertychanged); } //get indices visible list's data group private function getnewindices():vector.<int> { var indices:vector.<int> = new vector.<int>(2, true); var indicesinview:vector.<int> = infinitelist.datagroup.getitemindicesinview(); if (indicesinview.length > 0){ indices[0] = indicesinview[0]; } if (indicesinview.length > 1){ indices[1] = indicesinview[indicesinview.length - 1]; } return indices; } private function updateindices():void { var indices:vector.<int> = getnewindices(); if (indices.length > 0){ firstiteminview = indices[0]; if (indices.length > 1){ lastiteminview = indices[1]; } } } protected function leftcalendar_verticalscroll_propertychanged(event:propertychangeevent):void { switch (event.property){ case "verticalscrollposition": var indices:vector.<int> = getnewindices(); var oldindices:vector.<int> = getvisibleindices(); var newnum:number; if (indices[1] - indices[0] == 2 && (oldindices[0] != indices[0] && oldindices[1] != indices[1])){ //a new item in view. did scroll or down? if (oldindices[0] < indices[0]){ count++; trace(count + " : old[" + oldindices[0] + "," + oldindices[1] + "], new[" + indices[0] + "," + indices[1] + "]"); //newnum = number(listdata.getitemat(listdata.length - 1)) + 1; //trace("new number add: " + newnum); //trace("todo remove: " + listdata.getitemat(0)); fixitems({ addat : "top", removeat : "bottom", newvalue : newnum}); } else { trace("down : old[" + oldindices[0] + "," + oldindices[1] + "], new[" + indices[0] + "," + indices[1] + "]"); fixitems({ addat : "bottom", removeat : "top", newvalue : newnum}); } //update indices: updateindices(); var newones = getvisibleindices(); //seems getting new ones, next occurance of event handler doesn't pick new values! why? trace(count + " current[" + newones[0] + ", " + newones[1] + "]"); } break; } } protected function fixitems(data:object):void { var item:object; //add new item if (data.addat == "top"){ listdata.additemat(data.newvalue, 0); } else { listdata.additem(data.newvalue); } //remove 1 of existing ones if (data.removeat == "top"){ item = listdata.getitemat(0); trace("removing " + item); listdata.removeitemat(0); } else { item = listdata.getitemat(listdata.length - 1); trace("removing " + item); listdata.removeitemat(listdata.length - 1); } updateindices(); }
you can't use list. you'll have create own custom component scratch. components know of in flex uses finite dataprovider display information. if want infinite, you'll need create own component can handle range (or none whatsoever) , display appropriately , scroll it. sure clean items not displayed anymore (or reuse them) because severe memory leak.
Comments
Post a Comment