2

我在 spark Scroller 中有很多子文本输入。如果我有一个 ..z id,如何让 id 为“x”的 TextInput 成为焦点,并且滚动条也可以自动滚动到该子项?

我可以使用 x.setFocus(),但滚动条不会自动滚动到该项目?为什么?

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

谢谢,菲利普

4

4 回答 4

2

原因是 setFocus 只是使对象处于活动状态,它实际上并没有移动更改 ScrollBar 的 scrollPosition。对于像 List 这样更复杂的类,它更直接,但 Scroller 非常基础,所以它有点难。

要执行您想要的操作,您必须获取视口(您的组)内元素的索引,然后手动设置滚动位置。对于垂直布局,代码如下所示:

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

其中 'g' 是您要在 Scroller 中移动到的元素的 id。

=Ryan ryan@adobe.com

于 2009-09-01T06:22:32.720 回答
1

只需查看 Flex SDK,这里有一个 spark.components.List 方法,只需对您的 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;
    }
}
于 2011-04-26T16:32:33.013 回答
0

几个额外的考虑:

  1. 我的数据组中的项目不是恒定的高度,所以如果是这样的话,将滚动条设置为的更准确的参考是:

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

  2. 确保您的数据组未设置为使用虚拟化。我的是,我在运行时添加/删除元素时遇到错误。

于 2010-06-03T23:12:42.713 回答
0

getScrollPositionDeltaToElement 方法不考虑嵌套子项。为此,您可以使用 mx_internal 方法,如下所示:

/**
* 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)]);
   }
于 2012-10-17T16:29:50.973 回答