FLEX 4s: Scroller how to bring hidden component into view?

I have many child text inputs in the spark scroller. How can I get the TextInput with id "x" to come into focus if I have a..z id, also for the scrollbar to automatically scroll to that child?

I can use x.setFocus (), but the scrollbar doesn't automatically scroll to that element? why?

<s:Scroller id="scroller" width="100%" height="100">
        <s:Group id="group" width="100%" height="100" id="content">
            <s:TextInput id="a" text="" editable="true" width="100%" height="25" />
            <s:TextInput id="b" text="" editable="true" width="100%" height="25" />
            ....
        </s:Group>
</s:Scroller>

      

Thanks, Philip

+2


source to share


4 answers


The reason is that setFocus just makes the object active, it doesn't actually change the scrollPosition change from the ScrollBar. With more complex classes like List this is more straight forward, but the Scroller is pretty simple and therefore a little more complex.

To do what you want, you need to get the index of the element inside your viewport (your group) and then manually set the scrollPosition. For vertical layout, the code will look something like this:

var index:Number = group.getElementIndex(g);
var offset:Number = group.getElementAt(index).height;
scroller.viewport.verticalScrollPosition = index * offset;

      



Where 'g' is the id of the item you want to move to your scroller.

= Ryan ryan@adobe.com

+2


source


Just check the Flex SDK, here's the spark.components.List method, just use the same code for your DataGroup:



public function ensureIndexIsVisible(index:int):void
{
    if (!layout)
        return;

    var spDelta:Point = dataGroup.layout.getScrollPositionDeltaToElement(index);

    if (spDelta)
    {
        dataGroup.horizontalScrollPosition += spDelta.x;
        dataGroup.verticalScrollPosition += spDelta.y;
    }
}

      

+1


source


a couple of additional considerations:

  • The items in my data group are not constant height, so if so, a more accurate reference to set up the scroller would be:

    var y: int = group.getElementAt (index) .y; scroller.viewport.verticalScrollPosition = y;

  • Make sure your datagroup is not configured to use virtualization. Mine was and I had errors where items were added / removed at runtime.

0


source


The getScrollPositionDeltaToElement method ignores nested children. For this, you can use the mx_internal method as shown below:

/**
* Focus in handler to be used on form elements inside a Scroller. If the 
* widgets are inside a FormItem, this ensures that the entire FormItem is 
* scrolled into view. Also, if there are validations triggered on focusOut
* of the elements, the default behavior in Flex 4 is to display the error 
* messages at the top of the form. Because this affects the vertical position
* of each element, the logic to scroll the item into view must be delayed 
* until the next frame using callLater()
*
* NOTE: This uses a method, in the mx_internal namespace 
*/
    protected function widgetFocusInHandler(evt:FocusEvent):void {
        //we need to delay this because we may need to account 
        //for validation errors being display above the form.
        callLater(function(field:UIComponent) : void {
            //find the form item that wraps the input and scroll 
            //it into view

            var formItem:DisplayObjectContainer = field.parent;
            while (!(formItem is FormItem) && formItem) {
                 formItem = formItem.parent;
            }

            //if this item wasn't in a form item, then just use the 
            //widget itself
            if (!formItem) {
                formItem = field;   
            }

            var pt:Point = formItem.localToGlobal(new Point(0, formItem.height));

            pt = scrollWrapper.globalToLocal(pt);
            var layout:LayoutBase = scrollWrapper.layout;           
            var delta:Point = layout.mx_internal::getScrollPositionDeltaToAnyElement(field);
            if (delta) {
                if(delta.y > 0) {
                    layout.verticalScrollPosition += delta.y + 20;
                } else if (delta.y < 0) {
                    layout.verticalScrollPosition += delta.y - 20;
                }
            }

        }, [UIComponent(evt.currentTarget)]);
   }

      

0


source







All Articles