0

我有以下代码,可以滚动到特定的孩子。它工作正常,除非滚动到最后一个孩子。它工作正常,但这不是我期望的行为。问题是当滚动到最后一个孩子时,我希望孩子像其他孩子一样显示在视口的顶部。一些图表应该比文字更好地帮助这一点。

总结问题:

1.当滚动到最后一个孩子时,是否可以将它定位在视口中的(0,0)?

2.我有6个孩子,每个孩子身高200。contentHeight为1200,当verticalScrollPosition为0时,我调用viewport.getVerticalScrollPositionDelta(NavigationUnit.END),返回值为900。那么900是怎么计算出来的呢?

在此处输入图像描述 在此处输入图像描述

以下是代码:

<?xml version="1.0" encoding="utf-8"?>
<s:Application
    xmlns:fx="http://ns.adobe.com/mxml/2009" 
    xmlns:s="library://ns.adobe.com/flex/spark" 
    xmlns:mx="library://ns.adobe.com/flex/mx"
    creationComplete="init()"
    >
    <fx:Script>
        <![CDATA[
            import components.MockUI;

            import mx.collections.ArrayList;

            import spark.core.NavigationUnit;

            private function init():void {
                createElements();
            }

            private function createElements():void {
                for (var i:int = 0; i<6; i++) {
                    var ui:MockUI = new MockUI();
                    ui.text = "I'm  " + i + " !";
                    ui.width = 300;
                    ui.height = 200;
                    viewport.addElement(ui);
                }
            }

            //scroll to diffrent child, take attetion to the scrollRect
            private function scrollToChild(index:int):void {
                var delta:Number = returnSumHeight(index);
                viewport.verticalScrollPosition = delta;
                var scrollRect:Rectangle = viewport.scrollRect;
                trace("viewport contentHeight: ", viewport.contentHeight);
                trace("vp: ", viewport.verticalScrollPosition);
                trace("scrollRect: ", scrollRect);
            }

            private function handleScroll(unit:uint):void {
                trace("unit: ", unit);
                var delta:Number = viewport.getVerticalScrollPositionDelta(unit);
                trace("delta:", delta);
            }

            private function minus():void {
                viewport.verticalScrollPosition -= 10;
                trace("vp: ", viewport.verticalScrollPosition);
            }

            //return the sum height of children before index item
            private function returnSumHeight(index:int):Number {
                var sumHeight:Number = 0;
                for(var i:int=0; i<index; i++) {
                    sumHeight += viewport.getElementAt(i).height;
                }
                return sumHeight;
            }
        ]]>
    </fx:Script>
    <s:layout>
        <s:VerticalLayout horizontalAlign="center" paddingTop="100"/>
    </s:layout>
    <s:HGroup>
        <s:Label text="Select Child: "/>
        <s:ComboBox id="comboBox"
                    dataProvider="{new ArrayList([0,1,2,3,4,5])}"
                    selectedIndex="0"
                    change="scrollToChild(comboBox.selectedIndex)"/>
    </s:HGroup>
    <s:Scroller>
        <s:VGroup id="viewport" width="350" height="300" gap="0">
        </s:VGroup>
    </s:Scroller>
    <s:Button label="MINUS" click="minus()"/>
    <s:Button label="UP" click="handleScroll(NavigationUnit.UP)"/>
    <s:Button label="DOWN" click="handleScroll(NavigationUnit.DOWN)"/>
    <s:Button label="HOME" click="handleScroll(NavigationUnit.HOME)"/>
    <s:Button label="END" click="handleScroll(NavigationUnit.END)"/>
</s:Application>

莫奎:

package components {
    public class MockUI extends UIComponent {
        private var label:Label;

        private var _text:String;
        private var textChanged:Boolean = false;

        public function set text(value:String):void {
            if(value == _text) {
                return;
            }

            _text = value;
            textChanged = true;
            invalidateProperties();
        }

        public function get text():String {
            return _text;
        }

        override protected function createChildren():void {
            super.createChildren();

            label = new Label();
            addChild(label);
        }

        override protected function commitProperties():void {
            super.commitProperties();

            if(textChanged) {
                textChanged = false;
                label.text = _text;
            }
        }


        override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void {
            super.updateDisplayList(unscaledWidth, unscaledHeight);

            label.width = unscaledWidth/2.0;
            label.height = unscaledHeight/2.0;
            label.x = unscaledWidth/2.0;
            label.y = unscaledHeight/2.0;

            graphics.clear();
            graphics.lineStyle(2, 0xffff00);
            graphics.drawRect(0, 0, unscaledWidth, unscaledHeight);
            graphics.beginFill(0xff0000, 1);
            graphics.drawRect(0,0,unscaledWidth, unscaledHeight);
            graphics.endFill();
        }
    }
}
4

1 回答 1

1

滚动到最后一个孩子时,是否可以将其定位在视口中的 (0,0) 处?

不,由于您的视口/元素的大小,使用 Flex SDK 中的默认代码是不可能的。使用默认代码实现这一点的唯一方法是使您的视口与一个项目的大小相同(并且所有项目都具有相同的高度)。

Scroller不允许您滚动到内容的末尾(移动应用程序中的效果除外)。您可以扩展 Scroller 类以允许这样做。

我有 6 个孩子,每个孩子都有 200 高。contentHeight为1200,当verticalScrollPosition为0时,我调用viewport.getVerticalScrollPositionDelta(NavigationUnit.END),返回值为900。那么900是怎么计算出来的呢?

每个孩子的高度是 200,他们所在的容器的高度是 300 像素。因为滚动条不允许您滚动到内容的末尾,所以它将滚动位置的最大值限制为:contentHeight - viewportHeight (1200 - 300 = 900)。

将视口想象为(在这种情况下)在内容上垂直移动的东西。内容的高度为 1200 像素,但由于视口为 300 像素,因此我们无需将视口的 Y 位置设置为高于 900 像素即可看到内容的结尾。

于 2013-07-16T21:06:26.307 回答