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 のデフォルト コードでは、ビューポート/要素のサイズが原因で、それは不可能です。デフォルトのコードでこれを実現する唯一の方法は、ビューポートを 1 つのアイテムと同じサイズにすることです (すべてのアイテムの高さを同じにします)。

では、コンテンツの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 に答える