Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/apache-flex/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Apache flex 在LayoutBase中定位列表的目的是什么?_Apache Flex - Fatal编程技术网

Apache flex 在LayoutBase中定位列表的目的是什么?

Apache flex 在LayoutBase中定位列表的目的是什么?,apache-flex,Apache Flex,为列表编写自定义布局时,在LayoutBase类本身上使用horizontalScrollPosition/verticalScrollPosition属性(与layoutTarget上的相应属性相反)需要考虑哪些因素 以HorizontalLayout类为例,它总是引用和更新layoutTarget.horizontalScrollPosition。LayoutBase类的horizontalScrollPosition是否曾经被引用/使用过 澄清: 我真正想问的是: layout实例上的属性

为列表编写自定义布局时,在LayoutBase类本身上使用horizontalScrollPosition/verticalScrollPosition属性(与layoutTarget上的相应属性相反)需要考虑哪些因素

HorizontalLayout
类为例,它总是引用和更新
layoutTarget.horizontalScrollPosition
。LayoutBase类的horizontalScrollPosition是否曾经被引用/使用过

澄清: 我真正想问的是: layout实例上的属性与layoutTarget实例上的属性之间的关系是什么,何时应该使用它们

LayoutBase类的horizontalScrollPosition是否曾经被引用/使用过

是的,可以用

在代码find horizontalScrollPosition中,至少有3个使用此参数的函数


如果你能告诉我你到底想用它做什么,那就更好了。

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 <code>dropLocation</code>
 *  during a drag and drop gesture.
 *
 *  Called by the <code>showDropIndicator()</code> method to calculate the scroll 
 *  during drag-scrolling.
 *
 *  @param context A valid DropLocation object previously obtained
 *  by calling the <code>calculateDropLocation()</code> 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);
}
水平滚动位置

/**
 *  @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()

还让我们看看这部分代码

/**
*  Computes the <code>verticalScrollPosition</code> and 
*  <code>horizontalScrollPosition</code> deltas needed to 
*  scroll the element at the specified index into view.
* 
*  <p>This method attempts to minimize the change to <code>verticalScrollPosition</code>
*  and <code>horizontalScrollPosition</code>.</p>
* 
*  <p>If <code>clipAndEnableScrolling</code> is <code>true</code> 
*  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 <code>horizontalScrollPosition</code> and
*  <code>verticalScrollPosition</code> that scrolls the element completely 
*  within the scroll rectangle's bounds.</p>
* 
*  @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和HorizontalLayout中的差异,会怎么样

在HL中,它用于
私有函数updateDisplayList virtual():void
但在LayoutBase中没有这样的函数,因为LayoutBase只是一个基类,但它有另一个名为
公共函数updateDisplayList(宽度:数字,高度:数字):void
但它是空的

因此,如果我们试着思考所有这些函数都做了什么,imho,HL只是将standart
updateDisplayList
扩展到两个函数,一个是相同的,另一个是虚拟的

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();
}
因此,所有内容都是使用VirtualLayout,但它来自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. 
 *
 *  <p>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. </p>
 *  
 *  <p>To configure a container to use virtual layout, set the <code>useVirtualLayout</code> property 
 *  to <code>true</code> 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.</p>
 *
 *  <p><b>Note: </b>The BasicLayout class throws a run-time error if you set 
 *  <code>useVirtualLayout</code> to <code>true</code>.</p>
 * 
 *  <p>When <code>true</code>, layouts that support virtualization must use 
 *  the <code>target.getVirtualElementAt()</code> method, 
 *  rather than <code>getElementAt()</code>, and must only get the 
 *  elements they anticipate will be visible given the value of <code>getScrollRect()</code>.</p>
 * 
 *  <p>When <code>true</code>, the layout class must be able to compute
 *  the indices of the layout elements that overlap the <code>scrollRect</code> in its 
 *  <code>updateDisplayList()</code> method based exclusively on cached information, not
 *  by getting layout elements and examining their bounds.</p>
 * 
 *  <p>Typically virtual layouts update their cached information 
 *  in the <code>updateDisplayList()</code> method,
 *  based on the sizes and locations computed for the elements in view.</p>
 * 
 *  <p>Similarly, in the <code>measure()</code> method, virtual layouts should update the target's 
 *  measured size properties based on the <code>typicalLayoutElement</code> and other
 *  cached layout information, not by measuring elements.</p>
 * 
 *  <p>Containers cooperate with layouts that have <code>useVirtualLayout</code> = <code>true</code> 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 <code>getVirtualElementAt()</code> indices requested during
 *  the container's most recent <code>updateDisplayList()</code> invocation.</p>
 *
 *  @default false
 * 
 *  @see #getScrollRect
 *  @see #typicalLayoutElement
 *
 *  @langversion 3.0
 *  @playerversion Flash 10
 *  @playerversion AIR 1.5
 *  @productversion Flex 4
 */
所以这是你的答案,我想,我也认为写这个火花系统的人会更广泛地解释,我很高兴能帮助你得到正确的答案

问候

尤金

我可以用……但它有什么用呢?layout实例上的属性与layoutTarget实例上的属性之间的关系是什么?何时应该使用它们?您读过吗?是的,但不幸的是,这是直接从
IViewport
定义复制的,它只是用于horizontalScrollPosition的标准ASDoc。它没有告诉我任何关于如何使用该属性与布局相关的信息。
 /**
 *  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. 
 *
 *  <p>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. </p>
 *  
 *  <p>To configure a container to use virtual layout, set the <code>useVirtualLayout</code> property 
 *  to <code>true</code> 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.</p>
 *
 *  <p><b>Note: </b>The BasicLayout class throws a run-time error if you set 
 *  <code>useVirtualLayout</code> to <code>true</code>.</p>
 * 
 *  <p>When <code>true</code>, layouts that support virtualization must use 
 *  the <code>target.getVirtualElementAt()</code> method, 
 *  rather than <code>getElementAt()</code>, and must only get the 
 *  elements they anticipate will be visible given the value of <code>getScrollRect()</code>.</p>
 * 
 *  <p>When <code>true</code>, the layout class must be able to compute
 *  the indices of the layout elements that overlap the <code>scrollRect</code> in its 
 *  <code>updateDisplayList()</code> method based exclusively on cached information, not
 *  by getting layout elements and examining their bounds.</p>
 * 
 *  <p>Typically virtual layouts update their cached information 
 *  in the <code>updateDisplayList()</code> method,
 *  based on the sizes and locations computed for the elements in view.</p>
 * 
 *  <p>Similarly, in the <code>measure()</code> method, virtual layouts should update the target's 
 *  measured size properties based on the <code>typicalLayoutElement</code> and other
 *  cached layout information, not by measuring elements.</p>
 * 
 *  <p>Containers cooperate with layouts that have <code>useVirtualLayout</code> = <code>true</code> 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 <code>getVirtualElementAt()</code> indices requested during
 *  the container's most recent <code>updateDisplayList()</code> invocation.</p>
 *
 *  @default false
 * 
 *  @see #getScrollRect
 *  @see #typicalLayoutElement
 *
 *  @langversion 3.0
 *  @playerversion Flash 10
 *  @playerversion AIR 1.5
 *  @productversion Flex 4
 */