Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Adobe Flex/AIR: Scrolling a sub-component, not the whole window

I'm developing an application with Adobe Flex and AIR, and I've been banging my head against the wall trying to figure out how to solve a scrolling issue.

The basic structure of my main application window (simplified greatly) is this:

<?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>

The trouble is that the "MainContent" box might contain a huge list of subcomponents, and the presence of that long list causes a vertical scrollbar to appear at the highest level of the GUI, surrounding the "MainContainer" vbox.

It looks really silly, having scrollbars around the entire application window.

What I'm looking for instead is a solution where the scrollbar is only applied to the "MainContent" vbox (as well as the Navigation and HelpContent panels, if their content stretches past the window bounds).

I found a related question on StackOverflow, where the problem's solution was to use "autoLayout" and "verticalScrollPolicy" attributes on parent containers.

So I tried adding autoLayout="false" and verticalScrollPolicy="off" attributes to all of the parent containers, as well as verticalScrollPolicy="on" to the "MainContent" vbox. But the end-result of that experiment was that the content was simply clipped from the main container (and a useless scrollbar with no thumb was added to the MainContent vbox).

Anyone know how to solve this?

like image 330
benjismith Avatar asked Dec 10 '08 01:12

benjismith


2 Answers

An HBox or a VBox will try as hard as possible to display its content without scroll bars. This forces a parent container (often all the way up to the main Application) to be the one that must scroll if the content is too large to fit in the available bounds.

Behind the scenes, the HBox or VBox is setting the measuredMinWidth and measuredMinHeight properties in its measure() function to match the dimensions required by its children. The parent container will honor that recommendation and the task of scrolling moves up the display list.

hasseg's solution works in many cases because it stops the container from measuring, but it's kind of hacky. Here's what you can do without building replacement subclasses for your containers. On the container instance that you want to scroll, set minWidth or minHeight to 0. This will take precedence over the measuredMinWidth or measuredMinHeight properties of that container, allowing the parent to set the actual size to something more manageable.

like image 176
Josh Tynjala Avatar answered Oct 19 '22 18:10

Josh Tynjala


Found a solution.

Looks like the only way to prevent the VBox from aggressively extending its vertical space (and forcing its parents to grow scrollbars) is to wrap the VBox in a Canvas.

There's a handy little component here, called ScrollableVBox, which performs the workaround while taking care of a few bookkeping issues (like adding and removing children to the VBox, passing them around the Cavas wrapper).

like image 37
benjismith Avatar answered Oct 19 '22 19:10

benjismith