如何更改视口垂直滚动位置动态y

时间:2013-04-27 11:40:04

标签: flex4 scroller

我正在尝试使用滚动条滚动VGroup:

<s:Scroller id="scroller" width="100" height="100">

       <s:VGroup id="vp" width="100%" height="100%">

          <my:TripView id="one"/>  

          <my:TripView id="two"/>

           // if any more TripView.....

       </s:VGroup>

</s:Scroller>

TripView是动态生成的,因此VGroup contentHeight可能比viewPortHeight大得多。由于我可以在TripView中拖动东西,我想在拖动内容几乎移动到视图底部时更改vp.verticalScrollPosition,以便其他TripView可以在屏幕中。

1 个答案:

答案 0 :(得分:0)

最重要的是scrollRect。根据scrollRect更改verticalScrollPosition。要使用ScrollManager,您应该通过registerViewport函数注册视口。然后在事件监听器调用startScroll中监听mouseMove事件。以下是实施:

package utils {

import flash.display.Stage;
import flash.events.MouseEvent;
import flash.geom.Point;
import flash.geom.Rectangle;

import mx.core.IInvalidating;

import spark.components.Group;


public class ScrollManager {
    private var viewport:Group;
    private var stage:Stage;

    private var oldMovingMouseY:Number;

    private static var _instance:ScrollManager;

    //threshold for scrolling
    private const FUDGE:Number = 35;
    //scroll up speed
    private const UP_SCROLL_DELTA:int = 50;
    //scroll down speed
    private const DOWN_SCROLL_DELTA:int = 80;

    public function registerViewport(viewport:Group):void {
        this.viewport = viewport;
        this.stage = viewport.stage;
    }

    public static function getInstance():ScrollManager {
        if(_instance == null) {
            _instance = new ScrollManager();
        }
        return _instance;
    }

    public function startScroll(mouseEvent:MouseEvent):void {
        oldMovingMouseY = mouseEvent.stageY;
        stage.addEventListener(MouseEvent.MOUSE_MOVE, onMouseMove, false, 0, true);
        stage.addEventListener(MouseEvent.MOUSE_UP, onMouseUp, false, 0, true);
    }

    private function onMouseUp(event:MouseEvent):void {
        stage.removeEventListener(MouseEvent.MOUSE_MOVE, onMouseMove);
        stage.removeEventListener(MouseEvent.MOUSE_UP, onMouseUp);

        if (viewport is IInvalidating) {
            //viewport.callLater(IInvalidating(viewport).validateNow);
            //change VSP on scrollRect.y
            var rect:Rectangle = viewport.scrollRect;
            viewport.verticalScrollPosition = rect.y;
            trace("========final vsp ========", rect.y);
        }
    }

    private function onMouseMove(event:MouseEvent):void {
        var currentMouseX:Number = event.stageX;
        var currentMouseY:Number = event.stageY;
        trace("mouseY ", currentMouseY);

        //scroll direction
        var delta:Number = currentMouseY - oldMovingMouseY;
        var direction:int = (delta > 0) ? 1 : (delta < 0) ? -1: 0;
        var scrollDelta:Number = direction > 0 ? DOWN_SCROLL_DELTA : UP_SCROLL_DELTA;

        //current mousePoint in viewport coordination
        var localPoint:Point = viewport.globalToLocal(new Point(currentMouseX, currentMouseY));
        trace("localPoint: ", localPoint);
        var scrollRect:Rectangle = viewport.scrollRect;
        trace("viewport rect", scrollRect);

        //determine if need scroll
        if(needScroll(localPoint, scrollRect, direction)) {
            trace("direction  ", direction > 0 ? " UP": " DOWN");
            scrollRect.y += scrollDelta*direction;
            viewport.scrollRect = scrollRect;
            if (viewport is IInvalidating) {
                IInvalidating(viewport).validateNow();
            }
        }

        oldMovingMouseY = currentMouseY;
    }

    private function needScroll(localPoint:Point, scrollRect:Rectangle, direction:int):Boolean {
        var localY:Number = localPoint.y;
        var bottom:Number = scrollRect.bottom;
        var top:Number = scrollRect.top;

        if(direction > 0 && (localY + FUDGE) > bottom) {
            return true;
        }

        if(direction< 0 && (localY - FUDGE) < top) {
            return true;
        }

        return false;
    }
}

}