2010-10-06 96 views
1

我有一个由ArrayCollection为其dataProvider支持的Spark List(spark.components.List)。当有太多的行要显示时,List有一个垂直滚动条。我想要的是当一个新行被添加到列表中以便滚动到底部以显示新行时。当添加新数据时,Flex Spark List滚动到底部

我试着从ArrayCollection的侦听器调用List的ensureIndexIsVisible。这不起作用,因为列表尚未完全呈现新行。它要么滚动到倒数第二行,或者抛出该异常:

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] 

我确信,我的听众是设置列表的dataProvider之后添加到ArrayCollection中。希望在List有机会处理新行后,我会打电话给ensureIndexIsVisible。我的猜测是列表不会呈现该行,直到稍后发生的某个重绘事件(在我调用ensureIndexIsVisible之后)。

我也试过指定一个VerticalLayout并将它的verticalScrollPosition设置为过大的数字(如99999)。这有同样的问题 - 它滚动到最后一行的第二个问题。

那么,有没有办法滚动到Spark列表中新添加的行?我唯一能在互联网上找到的是poorly formatted flexcoders thread

+0

您是否尝试在'callLater'中调用'ensureIndexIsVisible()'?像'callLater(function():void {ensureIndexIsVisible(lastIndex)});' – 2010-10-07 18:04:08

+0

是的,我试过了,它不起作用,显然callLater没有足够晚的时间被调用。我确实使用了setTimeout,它确实有效,但这非常不合理。 – 2010-10-07 18:39:16

回答

1

我的解决办法是扩展List并覆盖updateDisplayList,它的工作原理:在Adobe's forums

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

见讨论。

+0

这只有时有效,你需要等待大约.03秒来调用这个,setTimeout的工作原理,但可能你需要一个CallLater工具类来处理这个。如果你需要一个能够很好地工作的消息,给我发消息... – JTtheGeek 2010-12-01 23:47:45

+0

'callLater(myList.ensureIndexIsVisible,[myData.length - 1])在某些情况下仍然会抛出异常 – 2012-11-03 10:17:00

4

而是为了覆盖updateDisplayList延长List的,我说我的List分量的监听器FlexEvent.UPDATE_COMPLETE和它的作品对我蛮好。

1

我发现,当ensureIndexIsVisible直接在插入到列表dataProvider后运行时,它不会精确地拉取列表中最后一项的位置。这看起来是因为绑定没有机会更新列表。对我来说最快的解决方案是在ensureIndexIsVisible上运行callLater。

_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

有点解释会让你的帖子更有价值;) – ForceMagic 2012-10-22 02:40:58

0

有同样的问题,这对我的作品 -

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

要滚动到更新的火花列表的底部,并 ensureIndexIsVisible太多无证麻烦? 我得到这个被处理的名单dataGroup时财产的物理高度工作...

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

你为什么不使用这样的:

SysLog.verticalScrollPosition = log.length-1; 

? 它为我工作;

相关问题