Как я могу заставить гибкий контейнер прокручиваться до последней позиции?

#apache-flex

#apache-flex

Вопрос:

Я создаю окно чата, очень похожее на этот пример

http://demo.seanhess.net/oneshots/scrolling.swf

Всякий раз, когда добавляется чат, я хочу, чтобы он полностью отображал последнее сообщение. Я использую maxVerticalScrollPosition для установки положения прокрутки в списке, но это всегда неправильно (см. Пример). Он пропускает его на строку или около того. Я пробовал это с обычным контейнером, и он делает то же самое. Если я использую maxVerticalScrollPosition 1, это вроде как работает, но если последнее сообщение особенно длинное, оно будет обрезано (отображается только верхнее).

Как я могу заставить его прокручиваться до фактического дна контейнера??

 <?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical">

    <mx:Script>
        <![CDATA[
            protected function addChat():void
            {
                collection.addItem(new String(input.text));
                list.verticalScrollPosition = list.maxVerticalScrollPosition;
                input.text = "";
            }
        ]]>
    </mx:Script>

    <mx:Panel width="400" height="290">
        <mx:List id="list" width="100%" height="100%" variableRowHeight="true">
            <mx:dataProvider>
                <mx:ArrayCollection id="collection"/>
            </mx:dataProvider>
            <mx:itemRenderer>
                <mx:Component>
                    <mx:Text text="{data}"/>
                </mx:Component>
            </mx:itemRenderer>
        </mx:List>
        <mx:HBox width="100%">
            <mx:TextInput id="input" width="100%" enter="addChat()"/>
            <mx:Button label="add" click="addChat()"/>
        </mx:HBox>
    </mx:Panel>
</mx:Application>
  

Ответ №1:

Разделите addChat() на две функции, addChat() и addChatScrollToEnd(). Добавьте элемент чата в addChat(), а затем вызовите Later(addChatScrollToEnd), который будет содержать строки прокрутки.

В качестве альтернативы вы можете вызвать list.validateNow(), но это не рекомендуется из соображений производительности.

Комментарии:

1. Я широко использую validateNow() без проблем с производительностью в нетривиальных приложениях. Если он запускается в огромном цикле, я бы этого избежал, но в этом случае рекомендуется использовать validateNow(). Я предпочитаю это вместо callLater(), потому что вы контролируете ситуацию и знаете, что действие выполняется сейчас.

Ответ №2:

У вас это должно сработать.

     <mx:Script>
            <![CDATA[
                    protected function addChat():void
                    {
                            collection.addItem(new String(input.text));
                            callLater(function() {
                                    list.verticalScrollPosition = list.maxVerticalScrollPosition;
                            });
                            input.text = "";
                    }
            ]]>
    </mx:Script>