Flex4.0 Spark List控件添加新Item自动滚动到底部

List 组件和DataGrid 组件不大一样,DataGrid组件本身就支持滚动到最下发并选中,在MX中,List也支持scrollToIndex()方法,但是Spark 的 List中,这个功能就有点复杂了。

一开始我注意到一个属性ensureIndexIsVisible,并且找到了Demo点击打开链接;但是在运用到我自己的项目中时,会出现一些状况导致list不下滑到最新的项目中(已选中最下方时候单击添加,就不会滚动)。代码如下:

<?xml version="1.0" encoding="utf-8"?>
<!-- http://blog.flexexamples.com/2010/05/12/scrolling-to-a-specific-index-in-a-spark-list-control-in-flex-4/ -->
<s:Application name="Spark_List_ensureIndexIsVisible_test"
        xmlns:fx="http://ns.adobe.com/mxml/2009"
        xmlns:s="library://ns.adobe.com/flex/spark"
        xmlns:mx="library://ns.adobe.com/flex/mx">
    <s:controlBarContent>
        <mx:Form>
            <mx:FormItem label="ensureIndexIsVisible():">
                <s:HSlider id="sl1" 
                        minimum="0"
                        maximum="{list.dataProvider.length-1}"
                        change="sl1_changeHandler(event);" />
            </mx:FormItem>
            <mx:FormItem label="selectedIndex:">
                <s:HSlider id="sl2"
                        minimum="-1"
                        maximum="{list.dataProvider.length-1}"
                        value="-1"/>
            </mx:FormItem>
        </mx:Form>
    </s:controlBarContent>
 
    <fx:Script>
        <![CDATA[
            protected function sl1_changeHandler(evt:Event):void {
                list.ensureIndexIsVisible(sl1.value);
            }
 
            protected function list_labelFunc(item:Object):String {
                return item.index + ") " + item.label;
            }
        ]]>
    </fx:Script>
 
    <s:List id="list"
            labelFunction="list_labelFunc" 
            selectedIndex="{sl2.value}"
            horizontalCenter="0" verticalCenter="0">
        <s:layout>
            <s:VerticalLayout gap="0"
                    horizontalAlign="contentJustify"
                    requestedRowCount="5" />
        </s:layout>
        <s:dataProvider>
            <s:ArrayList>
                <fx:Object label="One"       index="0" />
                <fx:Object label="Two"       index="1" />
                <fx:Object label="Three"     index="2" />
                <fx:Object label="Four"      index="3" />
                <fx:Object label="Five"      index="4" />
                <fx:Object label="Six"       index="5" />
                <fx:Object label="Seven"     index="6" />
                <fx:Object label="Eight"     index="7" />
                <fx:Object label="Nine"      index="8" />
                <fx:Object label="Ten"       index="9" />
                <fx:Object label="Eleven"    index="10" />
                <fx:Object label="Twelve"    index="11" />
                <fx:Object label="Thirteen"  index="12" />
                <fx:Object label="Fourteen"  index="13" />
                <fx:Object label="Fifteen"   index="14" />
                <fx:Object label="Sixteen"   index="15" />
                <fx:Object label="Seventeen" index="16" />
                <fx:Object label="Eighteen"  index="17" />
                <fx:Object label="Ninteen"   index="18" />
                <fx:Object label="Twenty"    index="19" />
            </s:ArrayList>
        </s:dataProvider>
    </s:List>
 
</s:Application>

后来又找到别的一些Demo点击打开链接,完美实现了下滑到最下的功能。作者说List对多行的Item下滑会出各种问题,然后就采用了一个循环来解决。我试过用calllater来避免使用while循环,但是没什么效果。代码如下

<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
               xmlns:s="library://ns.adobe.com/flex/spark"
               viewSourceURL="srcview/index.html">
    <fx:Script>
        <![CDATA[
            import spark.core.NavigationUnit;
            
            private function addMessage():void {
                // add the message
                chatList.dataProvider.addItem({label:message.text});
                
                // clear the text input
                message.text = "";
                
                // scroll to the bottom of the List to show this item
                scrollToBottom();
            }
            
            private function scrollToBottom():void {
                // update the verticalScrollPosition to the end of the List
                // virtual layout may require us to validate a few times
                var delta:Number = 0;
                var count:int = 0;
                while (count++ < 10){
                    chatList.validateNow();
                    delta = chatList.layout.getVerticalScrollPositionDelta(NavigationUnit.END);
                    chatList.layout.verticalScrollPosition += delta;
                    
                    if (delta == 0)
                        break;
                }
            }
        ]]>
    </fx:Script>
    
    <s:Panel title="Chat" defaultButton="{btn}" horizontalCenter="0" verticalCenter="0" width="300">
        <s:List id="chatList" alternatingItemColors="[#EEEEEE,#DDDDDD]" height="120" width="100%">
            <s:layout>
                <s:VerticalLayout horizontalAlign="justify" gap="0" />
            </s:layout>
            <s:dataProvider>
                <s:ArrayCollection id="dp" />
            </s:dataProvider>
        </s:List>
        
        <s:controlBarContent>
            <s:TextInput id="message" width="100%" />
            <s:Button id="btn" label="Send" click="addMessage()" />
        </s:controlBarContent>
    </s:Panel>
    
</s:Application>

作者对循环的解释如下:

Notice that there is a loop that possibly validates(操作) the List up to 10 times. This is because sometimes we may need to scroll several times in virtual layout as some items may not be loaded yet and their size is only estimated.

This loop is a little bit ugly and there is a bug filed at SDK-25740 to make this use case easier. Please vote for that issue if you would like to see that functionality implemented.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值