Spark List按鼠标位置滚动

时间:2011-03-13 00:48:18

标签: flex list scroll mouse

<s:List xmlns:fx="http://ns.adobe.com/mxml/2009" 
        xmlns:s="library://ns.adobe.com/flex/spark" 
        xmlns:mx="library://ns.adobe.com/flex/mx"

        mouseOver="scroller_mouseOver(event)" 
        height="308" width="110">

如上所示,我有一个带有MouseOver事件的Spark列表:

protected function scroller_mouseOver(e:MouseEvent):void { 
   CursorManager.removeAllCursors();      // Remove all previous Cursors
   if (mouseX > 24 && mouseX < 143) {
     if (mouseY > 220) {
          CursorManager.setCursor(downCursorSymbol);    // Down Cursor
     } else if (mouseY < 87) {
          CursorManager.setCursor(upCursorSymbol);     // Up Cursor
     }
     // Scroll as its Mouse Overed
     this.addEventListener(Event.ENTER_FRAME, scrollViaY);
     }
}

private function scrollViaY(e:Event):void {
   if (mouseX > 24 && mouseX < 143) {
     if (mouseY > 220) {
     this.layout.verticalScrollPosition += (mouseY - 220)*0.5; 
     }
     else if (mouseY < 87) {
     this.layout.verticalScrollPosition += (mouseY -86)*0.5; 
     }
   }
}

下图描述了我想跟踪悬停的区域。 List Upper & Lower hover tracking to scroll

问题:当我将鼠标悬停在列表的上部(红色)部分时(我希望列表向下滚动,鼠标位置越高,滚动的速度就越快)。类似地,如果鼠标悬停在底部(红色)部分上,则List向上滚动,鼠标悬停在较低的位置,列表滚动得越快。当前的代码确实有效 - 但是,跟踪显示明显: this.layout.verticalScrollPosition + =(mouseY - 220)* 0.5; 要么 this.layout.verticalScrollPosition + =(mouseY -86)* 0.5; ...正在提供跳跃效果,有没有办法让这些值更线性或更平滑地变化?

我创建了一个AnimateProperty,但只有当我想滚动到selectedIndex时才能正常工作。在这种情况下,我希望滚动器在鼠标悬停到特定红色区域时保持线性滚动,并增加当我滚动到任何一个极端时速度。

目标:当鼠标位于List的Bottom(红色部分)上方时,verticalScrollPosition会更快滚动,因为它比票证列表的中心更远......但是有跳跃效果还在继续,我想由于EnterFrame。与上半部分相同...光标越高,List应滚动得越快。

我觉得这是Flash CSx开发人员的常见问题。

1 个答案:

答案 0 :(得分:1)

我已经实现了类似的东西,除了它是一个水平滚动列表,并且我在列表的两侧使用了向左/向右滚动按钮,mouse_over效果由按钮触发,而不是列表(但是这不应该在调整代码时不成为障碍。

为了进行实际滚动,我使用了一个针对列表布局的动画效果,更具体地说,是布局的horizontalScrollPosition。这就是MXML代码的样子:

<s:Animate id="scrollAnimation" target="{listLayout}">
    <s:easer>
        <s:Linear easeInFraction="0" easeOutFraction="0" />
    </s:easer>

    <s:SimpleMotionPath id="scrollMotionPath" property="horizontalScrollPosition" />
</s:Animate>

easer是必要的,因为动画效果通常有3个动作阶段(加速,均匀运动和减速),所以默认情况下你会得到一个波浪滚动动作。 我在这个项目中使用了RobotLeft,因此视图的调解方式如下:

注册介体后,添加滚动按钮监听器:

viewComponent.scrollLeft.addEventListener(MouseEvent.MOUSE_OVER, onScrollLeft);
viewComponent.scrollRight.addEventListener(MouseEvent.MOUSE_OVER, onScrollRight);
viewComponent.scrollLeft.addEventListener(MouseEvent.MOUSE_OUT, onScrollOut);
viewComponent.scrollRight.addEventListener(MouseEvent.MOUSE_OUT, onScrollOut);

我们还需要添加一个监听器,以便我们可以判断滚动效果何时完成,因为我们可能需要重放它:

viewComponent.scrollEffect.addEventListener(EffectEvent.EFFECT_END, onScrollEnd);

我们现在可以实现滚动方法。由于视图是中介的,我们可以访问滚动效果,我们可以在这里引用它(以及路径)。这就是方法的样子:

private function scrollOnlineFriendsList(scrollBy:int):void
{
    // Set the scrollBy value and play the scrolling effect
    viewComponent.scrollMotionPath.valueBy = scrollBy;
    viewComponent.scrollEffect.play();

    // Store the scrollBy value in case the effect will need to be replayed,
    // if the mouse over event is still over the scrolling button/area
    this.scrollBy = scrollBy;

    canKeepScrolling = true;
}

最后,处理程序:

private function onScrollLeft(event:MouseEvent):void
{
    scrollOnlineFriendsList(-33);
}

private function onScrollRight(event:MouseEvent):void
{
    scrollOnlineFriendsList(33);
}

private function onScrollOut(event:MouseEvent):void
{
    canKeepScrolling = false;

    // If you would like the effect to continue playing
    // until it finishes the current scrolling operation,
    // once the mouse is no longer over a scroll button,
    // just comment this line
    viewComponent.scrollEffect.stop();
}

private function onScrollEnd(event:EffectEvent):void
{
    // When the scroll effect has finished playing,
    // if the mouse is still over the scroll button/area,
    // replay the effect
    if (canKeepScrolling)
        scrollOnlineFriendsList(scrollBy);
}