2010-09-01 10 views
1

當編寫一個列表的自定義佈局,需要給予使用上LayoutBase類本身horizo​​ntalScrollPosition的/ verticalScrollPosition屬性(相對於上layoutTarget相應的屬性)LayoutBase中List的xxScrollPosition的用途是什麼?

望着HorizontalLayout類的什麼注意事項一個例子,它總是引用和更新layoutTarget.horizontalScrollPosition。是否曾引用/使用過LayoutBase類的horizo​​ntalScrollPosition?

澄清: 什麼我真的問這裏是: 什麼是對的佈局實例的屬性之間的關係,VS的layoutTarget實例的屬性,以及何時應該使用哪一個?

回答

0

LayoutBase類的horizo​​ntalScrollPosition是否曾被引用/使用過?

是的,它可以使用。

please look!在代碼中查找horizo​​ntalScrollPosition至少有3個函數在這個參數中使用。

如果你能說出你想要做什麼,那會更好嗎?

+0

我可以用...但它有什麼作用?佈局實例上的屬性與layoutTarget實例上的屬性之間的關係以及每個應該在什麼時候使用? – 2010-09-01 19:05:36

+0

您是否閱讀過這個http://docs.huihoo.com/flex/4/spark/layouts/supportClasses/LayoutBase.html#horizo​​ntalScrollPosition? – Eugene 2010-09-01 19:33:35

+0

是的,但不幸的是,它直接從'IViewport'定義中複製,它只是horizo​​ntalScrollPosition的標準ASDoc。它並沒有告訴我任何有關財產如何被用於佈局的任何事情。 – 2010-09-01 20:28:08

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 <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); 
} 

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 <code>verticalScrollPosition</code> or 
* <code>horizontalScrollPosition</code> properties change. 
* 
* <p>The default implementation updates the target's <code>scrollRect</code> property by 
* calling <code>updateScrollRect()</code>. 
* Subclasses can override this method to compute other values that are 
* based on the current <code>scrollPosition</code> or <code>scrollRect</code>.</p> 
* 
* @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 <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和Horizo​​ntalLayout這些則params的區別是什麼這一部分?

在HL中使用它在private function updateDisplayListVirtual():void中使用,但在LayoutBase中沒有這樣的函數,因爲LayoutBase只是一個Base類,它有另一個名爲public function updateDisplayList(width:Number, height:Number):void但它是空的。

因此,如果我們試圖去思考所有這些功能是做什麼的,恕我直言,HL只是將標準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(); 
} 

因此,所有的東西是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. 
* 
* <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 
*/ 

所以它是你的答案,我想,也是我認爲人們誰寫了這Spark系統將更廣泛地解釋,這只是我的小小樂趣,可以幫助您獲得正確的答案。

問候
尤金