1

I have a VBox with some container elements in it. The VBox has a limited height and enables scrolling if its elements exceed its height.

Each of its child elements have a "header" element. In case of scrolling, I would like the header element to always be visible even if the container is "clipped" by the scrolling, exactly like the iPhone contacts application (see this question where the behavior is described, my headers correspond to A, B, etc.). I also have a bottom element that should behave similarly, sticking to the bottom of the visible area of the canvas.

I have been trying to accomplish this by listening on mouse events to detect scrolling and manually correct the position of the header and bottom elements like this:

private function updateTopBottomPosition():void {
    var host:DisplayObjectContainer = owner;

    var global0:Point = host.localToGlobal(new Point(0, 0));
    var global1:Point = host.localToGlobal(new Point(host.width, host.height));

    //transform parent global coordinates to local frame
    var local0:Point = this.globalToLocal(global0);
    var local1:Point = this.globalToLocal(global1);

    var maxTop:Number = this.height;
    var minBottom:Number = this.height; // - topLabel.height

    var top:Number = local0.y;
    top = Math.max(0, top);
    top = Math.min(this.height, top);

    topLocalDistance = top;

    var bottom:Number = this.height - local1.y;
    bottom = Math.max(0, bottom);
    bottom = Math.min(this.height, bottom);

    bottomLocalDistance = bottom;

    if(prevBottomLocalDistance == bottomLocalDistance && topLocalDistance == prevTopLocalDistance)
        return;

    prevBottomLocalDistance = bottomLocalDistance;
    prevTopLocalDistance = topLocalDistance;

    //while there is changes, try again
    setTimeout(updateTopBottomPosition, 1);
}

It does work okay, and I have uploaded the source code for a complete working prototype HERE.

Unfortunately, the user experience with this approach is bad; the components do not move fluently and the positioning does not always update correctly.

I have not been able to find a component or an approach that is able to achieve the effect in question seamlessly. I would be grateful if anyone could point me in direction of something that would be able to solve this problem.

Community
  • 1
  • 1
Thorkil Holm-Jacobsen
  • 7,287
  • 5
  • 30
  • 43

1 Answers1

0

Perhaps I've misuderstood, but any reason you can't just use an additional layout of nesting?

container
 - header container
 - vbox with scroller
Ian
  • 303
  • 3
  • 5
  • There are multiple headers inside the `VBox`, all need the 'sticky' feature. Haven't you seen the link I provided with the iPhone contacts as example? – Thorkil Holm-Jacobsen Jan 31 '14 at 18:40
  • I'm not clear why they need to be in the vbox. I was suggesting moving them outside into another container, then wrapping both of them in a container (group?). – Ian Jan 31 '14 at 19:22
  • I am not following, can you elaborate in your answer? The elements are in a `VBox` because the need to be stacked on top of each other. Each of the elements has a header that needs to be positioned dynamically according to the scroll position as described in the question. – Thorkil Holm-Jacobsen Jan 31 '14 at 19:52