2010-10-06 3 views
1

J'ai une liste Spark (spark.components.List) soutenue par un ArrayCollection pour son dataProvider. La liste a une barre de défilement verticale lorsqu'il y a trop de lignes à afficher. Ce que je veux c'est quand une nouvelle ligne est ajoutée à la liste pour qu'elle défile vers le bas pour montrer cette nouvelle ligne.Flex Spark List défile vers le bas lorsque de nouvelles données sont ajoutées

J'ai essayé d'appeler la liste ensureIndexIsVisible d'un écouteur sur ArrayCollection. Cela ne fonctionne pas car la liste n'a pas encore entièrement rendu la nouvelle ligne. Il soit faites défiler jusqu'à la seconde de la dernière ligne, ou jeter l'exception:

Error: invalidIndex 
at spark.layouts.supportClasses::LinearLayoutVector/start()[E:\dev\4.0.0\frameworks\projects\spark\src\spark\layouts\supportClasses\LinearLayoutVector.as:893] 
at spark.layouts.supportClasses::LinearLayoutVector/getBounds()[E:\dev\4.0.0\frameworks\projects\spark\src\spark\layouts\supportClasses\LinearLayoutVector.as:1117] 
at spark.layouts::VerticalLayout/getElementBounds()[E:\dev\4.0.0\frameworks\projects\spark\src\spark\layouts\VerticalLayout.as:852] 
at spark.layouts.supportClasses::LayoutBase/http://www.adobe.com/2006/flex/mx/internal::getScrollPositionDeltaToElementHelper()[E:\dev\4.0.0\frameworks\projects\spark\src\spark\layouts\supportClasses\LayoutBase.as:1367] 
at spark.layouts.supportClasses::LayoutBase/getScrollPositionDeltaToElement()[E:\dev\4.0.0\frameworks\projects\spark\src\spark\layouts\supportClasses\LayoutBase.as:1348] 
at spark.components::List/ensureIndexIsVisible()[E:\dev\4.0.0\frameworks\projects\spark\src\spark\components\List.as:2105] 

Je me suis assuré que mon écouteur est ajouté à la ArrayCollection après la mise en dataProvider Liste. L'espoir est que j'appellerais ensureIndexIsVisible après que la liste ait eu l'occasion de traiter la nouvelle rangée. Ma conjecture est que la liste ne rend pas la ligne jusqu'à quelque événement de redessiner qui se produit plus tard (après que j'ai appelé ensureIndexIsVisible).

J'ai également essayé de spécifier un VerticalLayout et de définir son verticalScrollPosition à un nombre trop grand (comme 99999). Cela a le même problème - il défile à la seconde de la dernière rangée.

Alors, existe-t-il un moyen de faire défiler jusqu'à une nouvelle ligne ajoutée dans une liste Spark? Le seul que j'ai pu trouver sur Internet est ce poorly formatted flexcoders thread.

+0

Avez-vous essayé d'appeler 'ensureIndexIsVisible()' dans un 'callLater'? Comme 'callLater (function(): void {ensureIndexIsVisible (lastIndex)});' –

+0

Oui, j'ai essayé cela et cela n'a pas fonctionné, apparemment callLater n'est pas appelé plus tard.J'ai utilisé setTimeout et ça marche, mais c'est très bizarre. –

Répondre

1

était à ma solution étendre List et passer outre updateDisplayList, qui fonctionne:

protected override function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void 
{ 
    super.updateDisplayList(unscaledWidth, unscaledHeight); 
    // call ensureIndexIsVisible here 
} 

Voir la discussion sur Adobe's forums.

+0

cela ne fonctionne que parfois, vous devez attendre environ 0,03 secondes pour appeler cela, setTimeout fonctionne, mais vous avez probablement besoin d'une classe utilitaire CallLater pour gérer cela pour vous. Message moi si vous en avez besoin qui fonctionne bien ... – JTtheGeek

+0

'callLater (myList.ensureIndexIsVisible, [myData.length - 1])' jette toujours des exceptions dans certains cas –

4

Au lieu d'étendre List afin de passer outre updateDisplayList, j'ai ajouté un auditeur à l'FlexEvent.UPDATE_COMPLETE sur mon List composant et il fonctionne très bien pour moi.

1

J'ai trouvé que lorsque ensureIndexIsVisible est exécuté directement après une insertion dans un dataProvider de liste, il ne tire pas précisément la position du dernier élément de la liste. Cela semble être dû au fait que la liaison n'a pas eu l'occasion de mettre à jour la liste. La solution la plus rapide pour moi était d'exécuter un callLater sur ensureIndexIsVisible.

_acGuestBookMessages.addItemAt(obj, _acGuestBookMessages.length); 
var arr:Array = [_acGuestBookMessages.length-1]; 
callLater(lstGuestBookMessages.ensureIndexIsVisible, arr); 
0
if(itemsList && itemsList.scroller && 
    itemsList.scroller.verticalScrollBar && 
    itemsList.scroller.verticalScrollBar.visible){ 

     itemsList.scroller.verticalScrollBar.value = 
      itemsList.scroller.verticalScrollBar.maximum; 

} 
+0

Une petite explication rendrait votre message plus précieux;) – ForceMagic

0

était d'avoir le même problème, cela fonctionne pour moi -

if(chatCollection.length > 0) 
{ 
    chatList.validateNow(); 
    chatList.ensureIndexIsVisible(chatCollection.length - 1); 
} 
1

Vous voulez faire défiler en bas d'une liste d'allumage de mise à jour et ensureIndexIsVisible est trop de problèmes en situation irrégulière? Je suis arrivé que cela fonctionne en traitant à la hauteur physique des biens dataGroup sur la liste ...

function newMessage(...) 
{ 
    messages.addItemAt(msg, messages.length);    
    messages.refresh(); 
    scrollToBottom(); 
} 

function scrollToBottom():void 
{ 
    messagesList.addEventListener("updateComplete", scrollUpdate); 
} 

private function scrollUpdate(e:Event):void 
{ 
    messagesList.removeEventListener("updateComplete", scrollUpdate); 
    messagesList.dataGroup.verticalScrollPosition = messagesList.dataGroup.contentHeight - messagesList.dataGroup.height; 
} 
0

pourquoi ne pas utiliser quelque chose comme ceci:

SysLog.verticalScrollPosition = log.length-1; 

?? son travail pour moi;

Questions connexes