滚动特定的孩子进入视图

时间:2013-07-15 08:38:23

标签: flex4 scroll scrollview

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

摘要问题:

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

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

enter image description here enter image description here

以下是代码:

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

MOCKUI:

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();
        }
    }
}

1 个答案:

答案 0 :(得分: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像素以上,以查看内容的结尾。