1


0

ListのLayoutBaseのxxScrollPositionの目的は何ですか?

Listのカスタムレイアウトを記述するとき、layoutBaseクラス自体のhorizo​​ntalScrollPosition / verticalScrollPositionプロパティを使用するために考慮する必要がある考慮事項(layoutTargetの対応するプロパティとは対照的に)

Horizo​​ntalLayout`クラスを例として見ると、 layoutTarget.horizo​​ntalScrollPosition`を常に参照および更新します。 LayoutBaseクラスのhorizo​​ntalScrollPositionはこれまでに参照/使用されていますか?

*明確化:*ここで私が本当に求めているのは、レイアウトインスタンスのプロパティと、layoutTargetインスタンスのプロパティとの関係と、それぞれをいつ使用すべきかということです。

2 Answer


0


_ LayoutBaseクラスのhorizo​​ntalScrollPositionはこれまでに参照/使用されていますか? _

はい、使用できます。

http://opensource.adobe.com/svn/opensource/flex/sdk/trunk/frameworks/projects/spark/src/spark/layouts/supportClasses/LayoutBase.as [ご覧ください!]のコードでhorizo​​ntalScrollPositionを見つけてくださいこのパラメーターが使用された少なくとも3つの関数。

あなたがそれで何をしたいのかを正確に伝えるならば、それはより良いでしょうか?


0


  • layoutTarget *

/**
 *  @private
 *  Work-around the Player globalToLocal and scrollRect changing before
 *  a frame is updated.
 */
private function globalToLocal(x:Number, y:Number):Point
{
    var layoutTarget:GroupBase = target;
    var parent:DisplayObject = layoutTarget.parent;
    var local:Point = parent.globalToLocal(new Point(x, y));
    local.x -= layoutTarget.x;
    local.y -= layoutTarget.y;

    var scrollRect:Rectangle = getScrollRect();
    if (scrollRect)
    {
        local.x += scrollRect.x;
        local.y += scrollRect.y;
    }
    return local;
}

これも

/**
 *  Calculates how much to scroll for the specified dropLocation
 *  during a drag and drop gesture.
 *
 *  Called by the showDropIndicator() method to calculate the scroll
 *  during drag-scrolling.
 *
 *  @param context A valid DropLocation object previously obtained
 *  by calling the calculateDropLocation() method.
 *
 *  @param elapsedTime The duration, in milliseconds, since the drag scrolling start.
 *
 *  @return How much to drag scroll, or null if drag-scrolling is not needed.
 *
 *  @see spark.layouts.supportClasses.DropLocation
 *  @see #calculateDropIndex()
 *  @see #calculateDropIndicatorBounds()
 *
 *  @langversion 3.0
 *  @playerversion Flash 10
 *  @playerversion AIR 1.5
 *  @productversion Flex 4
 */
protected function calculateDragScrollDelta(dropLocation:DropLocation, elapsedTime:Number):Point
{
    var layoutTarget:GroupBase = target;
    if (layoutTarget.numElements == 0)
        return null;

    var scrollRect:Rectangle = getScrollRect();
    if (!scrollRect)
        return null;

    // Make sure that the drag-scrolling regions don't overlap
    var x:Number = dropLocation.dropPoint.x;
    var y:Number = dropLocation.dropPoint.y;

    var horizontalRegionSize:Number = Math.min(dragScrollRegionSizeHorizontal, layoutTarget.width/2);
    var verticalRegionSize:Number = Math.min(dragScrollRegionSizeVertical, layoutTarget.height/2);
    // Return early if the mouse is outside of the drag-scroll region.
    if (scrollRect.left + horizontalRegionSize < x && x < scrollRect.right - horizontalRegionSize &&
        scrollRect.top + verticalRegionSize < y && y < scrollRect.bottom - verticalRegionSize )
        return null;

    if (elapsedTime < dragScrollInitialDelay)
        return new Point(); // Return zero point to continue firing events, but not actually scroll.
    elapsedTime -= dragScrollInitialDelay;

    // Speedup based on time elapsed
    var timeSpeedUp:Number = Math.min(elapsedTime, 2000) / 2000;
    timeSpeedUp *= 3;
    timeSpeedUp += 1;
    timeSpeedUp *= timeSpeedUp * dragScrollSpeed * dragScrollInterval / 50;

    var minDeltaX:Number = -scrollRect.left;
    var minDeltaY:Number = -scrollRect.top;
    var maxDeltaY:Number = target.contentHeight - scrollRect.bottom;
    var maxDeltaX:Number = target.contentWidth - scrollRect.right;

    var deltaX:Number = 0;
    var deltaY:Number = 0;

    if (minDeltaX != 0 && x - scrollRect.left < horizontalRegionSize)
    {
        // Scroll left
        deltaX = 1 - (x - scrollRect.left) / horizontalRegionSize;
        deltaX *=  deltaX * timeSpeedUp;
        deltaX = -Math.round(deltaX) - 1;
    }
    else  if (maxDeltaX != 0 && scrollRect.right - x < horizontalRegionSize)
    {
        // Scroll right
        deltaX = 1 - (scrollRect.right - x) / horizontalRegionSize;
        deltaX *= deltaX * timeSpeedUp;
        deltaX = Math.round(deltaX) + 1;
    }

    if (minDeltaY != 0 && y - scrollRect.top < verticalRegionSize)
    {
        // Scroll up
        deltaY = 1 - (y - scrollRect.top) / verticalRegionSize;
        deltaY *=  deltaY * timeSpeedUp;
        deltaY = -Math.round(deltaY) - 1;
    }
    else  if (maxDeltaY != 0 && scrollRect.bottom - y < verticalRegionSize)
    {
        // Scroll down
        deltaY = 1 - (scrollRect.bottom - y) / verticalRegionSize;
        deltaY *= deltaY * timeSpeedUp;
        deltaY = Math.round(deltaY) + 1;
    }

    deltaX = Math.max(minDeltaX, Math.min(maxDeltaX, deltaX));
    deltaY = Math.max(minDeltaY, Math.min(maxDeltaY, deltaY));

    if (deltaX == 0 && deltaY == 0)
        return null;
    return new Point(deltaX, deltaY);
}
  • horizo​​ntalScrollPosition *

/**
 *  @private
 *  Updates the scroll position and dispatches a DragEvent.
 */
private function dragScroll(event:TimerEvent):void
{
    // Scroll the target
    horizontalScrollPosition += _dragScrollDelta.x;
    verticalScrollPosition += _dragScrollDelta.y;

    // Validate target before dispatching the event
    target.validateNow();

    // Re-dispatch the event so that the drag initiator handles it as if
    // the DragProxy is dispatching in response to user input.
    // Always switch over to DRAG_OVER, don't re-dispatch DRAG_ENTER
    var dragEvent:DragEvent = new DragEvent(DragEvent.DRAG_OVER,
                                            _dragScrollEvent.bubbles,
                                            _dragScrollEvent.cancelable,
                                            _dragScrollEvent.dragInitiator,
                                            _dragScrollEvent.dragSource,
                                            _dragScrollEvent.action,
                                            _dragScrollEvent.ctrlKey,
                                            _dragScrollEvent.altKey,
                                            _dragScrollEvent.shiftKey);

    dragEvent.draggedItem = _dragScrollEvent.draggedItem;
    dragEvent.localX = _dragScrollEvent.localX;
    dragEvent.localY = _dragScrollEvent.localY;
    dragEvent.relatedObject = _dragScrollEvent.relatedObject;
    _dragScrollEvent.target.dispatchEvent(dragEvent);
}

そしてこれも:

public function set horizontalScrollPosition(value:Number):void
{
    if (value == _horizontalScrollPosition)
        return;

    _horizontalScrollPosition = value;
    scrollPositionChanged();
}

`scrollPositionChanged();`も見てみましょう

 /**
 *  Called when the verticalScrollPosition or
 *  horizontalScrollPosition properties change.
 *
 *  The default implementation updates the target's scrollRect property by
 *  calling updateScrollRect().
 *  Subclasses can override this method to compute other values that are
 *  based on the current scrollPosition or scrollRect.
 *
 *  @see #updateScrollRect()
 *
 *  @langversion 3.0
 *  @playerversion Flash 10
 *  @playerversion AIR 1.5
 *  @productversion Flex 4
 */
protected function scrollPositionChanged():void
{
    var g:GroupBase = target;
    if (!g)
        return;

    updateScrollRect(g.width, g.height);
}

また、コードのこの部分を見てみましょう

/**
*  Computes the verticalScrollPosition and
*  horizontalScrollPosition deltas needed to
*  scroll the element at the specified index into view.
*
*  This method attempts to minimize the change to verticalScrollPosition
*  and horizontalScrollPosition.
*
*  If clipAndEnableScrolling is true
*  and the element at the specified index is not
*  entirely visible relative to the target's scroll rectangle, then
*  return the delta to be added to horizontalScrollPosition and
*  verticalScrollPosition that scrolls the element completely
*  within the scroll rectangle's bounds.
*
*  @param index The index of the element to be scrolled into view.
*
*  @return A Point that contains offsets to horizontalScrollPosition
*      and verticalScrollPosition that will scroll the specified
*      element into view, or null if no change is needed.
*      If the specified element is partially visible and larger than the
*      scroll rectangle, meaning it is already the only element visible, then
*      return null.
*      If the specified index is invalid, or target is null, then
*      return null.
*      If the element at the specified index is null or includeInLayout
*      false, then return null.
*
*  @see #clipAndEnableScrolling
*  @see #verticalScrollPosition
*  @see #horizontalScrollPosition
*  @see #udpdateScrollRect()
*
*  @langversion 3.0
*  @playerversion Flash 10
*  @playerversion AIR 1.5
*  @productversion Flex 4
*/
public function getScrollPositionDeltaToElement(index:int):Point

そして、LayoutBaseとHorizo​​ntalLayoutのこれらのパラメーターの違いについて話したらどうでしょうか?

HLでは、 private function updateDisplayListVirtual():void`で使用しましたが、LayoutBaseにはそのような関数はありません。LayoutBaseがそのままBaseクラスであるが、 public function updateDisplayList(width:Number、 height:Number):void`しかし空です。

したがって、これらのすべての関数が何をするのかを考えてみると、HLはスタンダート `updateDisplayList`を2つの関数に拡張し、一方は同じでもう一方は仮想です。

HLには仮想が必要ですか? どれどれ:

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

    var layoutTarget:GroupBase = target;
    if (!layoutTarget)
        return;

    if ((layoutTarget.numElements == 0) || (unscaledWidth == 0) || (unscaledHeight == 0))
    {
        setColumnCount(0);
        setIndexInView(-1, -1);
        if (layoutTarget.numElements == 0)
            layoutTarget.setContentSize(paddingLeft + paddingRight, paddingTop + paddingBottom);
        return;
    }

    if (useVirtualLayout)
        updateDisplayListVirtual();
    else
        updateDisplayListReal();
}

したがって、すべてのものは* useVirtualLayout *ですが、LayoutBaseからのものであり、以下を確認できます。

 /**
 *  A container can hold any number of children.
 *  However, each child requires an instance of an item renderer.
 *  If the container has many children, you might notice performance degradation
 *  as you add more children to the container.
 *
 *  Instead of creating an item renderer for each child,
 *  you can configure the container to use a virtual layout.
 *  With virtual layout, the container reuses item renderers so that it only creates
 *  item renderers for the currently visible children of the container.
 *  As a child is moved off the screen, possible by scrolling the container,
 *  a new child being scrolled onto the screen can reuse its item renderer.
 *
 *  To configure a container to use virtual layout, set the useVirtualLayout property
 *  to true for the layout associated with the container.
 *  Only the DataGroup or SkinnableDataContainer with the VerticalLayout,
 *  HorizontalLayout, and TileLayout supports virtual layout.
 *  Layout subclasses that do not support virtualization must prevent changing
 *  this property.
 *
 *  Note: The BasicLayout class throws a run-time error if you set
 *  useVirtualLayout to true.
 *
 *  When true, layouts that support virtualization must use
 *  the target.getVirtualElementAt() method,
 *  rather than getElementAt(), and must only get the
 *  elements they anticipate will be visible given the value of getScrollRect().
 *
 *  When true, the layout class must be able to compute
 *  the indices of the layout elements that overlap the scrollRect in its
 *  updateDisplayList() method based exclusively on cached information, not
 *  by getting layout elements and examining their bounds.
 *
 *  Typically virtual layouts update their cached information
 *  in the updateDisplayList() method,
 *  based on the sizes and locations computed for the elements in view.
 *
 *  Similarly, in the measure() method, virtual layouts should update the target's
 *  measured size properties based on the typicalLayoutElement and other
 *  cached layout information, not by measuring elements.
 *
 *  Containers cooperate with layouts that have useVirtualLayout = true by
 *  recycling item renderers that were previously constructed, but are no longer in use.
 *  An item is considered to be no longer in use if its index is not
 *  within the range of getVirtualElementAt() indices requested during
 *  the container's most recent updateDisplayList() invocation.
 *
 *  @default false
 *
 *  @see #getScrollRect
 *  @see #typicalLayoutElement
 *
 *  @langversion 3.0
 *  @playerversion Flash 10
 *  @playerversion AIR 1.5
 *  @productversion Flex 4
 */

それがあなたの答えだと思います。このSparkシステムを書いた人たちがもっと広く説明してくれると思います。これはあなたが正しい答えを得るのを助ける私の小さな喜びです。

よろしく+ユージーン