添加新数据时,Flex Spark List会滚动到底部

时间:2010-10-06 19:22:39

标签: flex flash

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

我尝试从ArrayCollection上的侦听器调用List的ensureIndexIsVisible。这不起作用,因为List尚未完全呈现新行。它将滚动到最后一行的第二行,或抛出异常:

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]

我确保在设置List的dataProvider后将我的侦听器添加到ArrayCollection中。希望是在List有机会处理新行之后我会调用ensureIndexIsVisible。我的猜测是List直到稍后发生一些重绘事件(在我调用ensureIndexIsVisible之后)才会呈现该行。

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

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

6 个答案:

答案 0 :(得分:4)

我没有扩展List以覆盖updateDisplayList,而是在FlexEvent.UPDATE_COMPLETE组件的List上添加了一个监听器,它对我来说很合适。

答案 1 :(得分:1)

我的解决方案是扩展List并覆盖updateDisplayList,其工作原理为:

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

见关于Adobe's forums的讨论。

答案 2 :(得分:1)

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

_acGuestBookMessages.addItemAt(obj, _acGuestBookMessages.length);
var arr:Array = [_acGuestBookMessages.length-1];
callLater(lstGuestBookMessages.ensureIndexIsVisible, arr);

答案 3 :(得分:1)

想要滚动到更新火花列表的底部并且 ensureIndexIsVisible 是无太多无证的麻烦? 我通过处理List ...

上的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;
}

答案 4 :(得分:0)

if(itemsList && itemsList.scroller && 
   itemsList.scroller.verticalScrollBar && 
   itemsList.scroller.verticalScrollBar.visible){

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

}

答案 5 :(得分:0)

遇到同样的问题,这对我有用 -

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