Adobe Flex / AIR: прокрутка субкомпонента, а не всего окна

Я разрабатываю приложение с помощью Adobe Flex и AIR, и я бился головой о стену, пытаясь понять, как решить проблему с прокруткой.

Основная структура моего главного окна приложения (сильно упрощенная) такова:

<?xml version="1.0" encoding="utf-8"?>
<mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml"
   paddingTop="0" paddingRight="0" paddingBottom="0" paddingLeft="0"
   width="800" height="600" layout="vertical" verticalAlign="top" 
>
   <mx:VBox id="MainContainer" width="100%" height="100%">
      <mx:Panel id="Toolbars" width="100%" height="25" />
      <mx:HDividedBox width="100%" height="100%" >
         <mx:Panel id="Navigation" minWidth="200" height="100%" />
         <mx:VBox id="MainContent" width="100%">
            <mx:Panel width="100%" height="200" />
            <mx:Panel width="100%" height="200" />
            <mx:Panel width="100%" height="200" />
            <mx:Panel width="100%" height="200" />
            <mx:Panel width="100%" height="200" />
         </mx:VBox>
         <mx:Panel id="HelpContent" minWidth="200" height="100%" />
      </mx:HDividedBox>
      <mx:Panel id="FooterContent" width="100%" height="25" />
   </mx:VBox>
</mx:WindowedApplication>

Проблема в том, что поле «MainContent» может содержать огромный список подкомпонентов, и наличие этого длинного списка приводит к появлению вертикальной полосы прокрутки на самом высоком уровне графического интерфейса пользователя, окружающего vbox «MainContainer».

Это выглядит действительно глупо, имея полосы прокрутки вокруг всего окна приложения.

Вместо этого я ищу решение, в котором полоса прокрутки применяется только к vbox «MainContent» (а также к панелям Navigation и HelpContent, если их содержимое выходит за границы окна).

Я нашел связанный вопрос на StackOverflow, где решение проблемы заключалось в использовании атрибутов autoLayout и verticalScrollPolicy в родительских контейнерах.

Поэтому я попытался добавить атрибуты autoLayout = "false" и verticalScrollPolicy = "off" ко всем родительским контейнерам, а также verticalScrollPolicy = "on" в vbox "MainContent". Но конечным результатом этого эксперимента было то, что содержимое было просто вырезано из основного контейнера (и в vbox MainContent была добавлена ​​бесполезная полоса прокрутки без большого пальца).

Кто-нибудь знает, как это решить?


person benjismith    schedule 10.12.2008    source источник


Ответы (4)


HBox или VBox будут стараться изо всех сил отображать свое содержимое без полос прокрутки. Это заставляет родительский контейнер (часто вплоть до основного приложения) быть тем, который должен прокручиваться, если содержимое слишком велико, чтобы поместиться в доступных границах.

За кулисами HBox или VBox задают свойства measureMinWidth и measureMinHeight в своей функции measure (), чтобы они соответствовали размерам, требуемым его дочерними элементами. Родительский контейнер будет соблюдать эту рекомендацию, и задача прокрутки перемещается вверх по списку отображения.

Решение hasseg работает во многих случаях, потому что не позволяет контейнеру измерять, но это своего рода хакерство. Вот что вы можете сделать, не создавая заменяющие подклассы для ваших контейнеров. В экземпляре контейнера, который вы хотите прокрутить, установите minWidth или minHeight на 0. Это будет иметь приоритет над свойствами measureMinWidth или measureMinHeight этого контейнера, позволяя родителю установить фактический размер на что-то более управляемое.

person Josh Tynjala    schedule 11.12.2008

Нашел решение.

Похоже, что единственный способ предотвратить агрессивное расширение вертикального пространства VBox (и принуждение его родителей к увеличению полос прокрутки) - это обернуть VBox в Canvas.

здесь есть удобный небольшой компонент, называемый ScrollableVBox, который выполняет обходной путь, заботясь о некоторых бухгалтерских записях. проблемы (например, добавление и удаление дочерних элементов в VBox, передача их через оболочку Cavas).

person benjismith    schedule 10.12.2008

Вместо того, чтобы оборачивать VBox в Canvas, установите для свойства minHeight VBox, у которого вы хотите иметь полосу прокрутки, значение 0.

person abedurftig    schedule 26.01.2011

Ваша проблема очень похожа на ту, с которой я боролся некоторое время назад. Я нашел свой ответ от это обсуждение: просто отключите measure() реализацию Box.

Это было довольно простое решение, которое отлично сработало в моем случае и не вызвало «побочного ущерба». Ваши результаты могут отличаться.

package whatever
{
    import mx.containers.Box;

    /**
    * A Box that has no measure() implementation.
    * 
    * <p>
    * See http://old.nabble.com/-flex_india%3A3318--Size-layout-issues-with-respect-to-parent-containers-to12882767.html
   *  for more info.
    * </p>
    */
    public class NonMeasuredBox extends Box
    {
        /**
        * Constructor
        */
        public function NonMeasuredBox():void
        {
            super();
        }

        override protected function measure():void { /* disabled */ }
    }
}
person hasseg    schedule 10.12.2008
comment
Я попробую позже днем. Однако я предполагаю, что эта мера отключения затрудняет изменение размера контейнера по горизонтали. Я просто хочу исправить проблему вертикальной прокрутки. - person benjismith; 10.12.2008
comment
Вы совершенно правы - это довольно радикальный прием, но он может быть полезен в некоторых конкретных ситуациях (например, в моей). - person hasseg; 10.12.2008