具有不同列数的列表 [英] List with different column count
问题描述
如图所示(这是由PhotoShop绘制的,尚未实现),我想实现一个这样的List
.它有不同的列数,比如第一行只有一个项目,其他有两个项目.我尝试使用 itemRendererFunction
来检测不同的项目(第一行视为 rendererA,其他视为另一个 rendererB),但没有用.
As the pic show(This is drawn by PhotoShop, not implemented yet), I want to implemnt a List
like this one. It has different column count, say the first row has only one item, and the others have two items . I tried to use itemRendererFunction
to detect the different item(the first row treat as a rendererA, the others treat as another rendererB),but it didn't work.
推荐答案
这个问题最干净的解决方案是创建自定义布局(我们在评论中讨论了 Romi 的解决方案最终会导致太多问题).然而,这通常不是一件容易的事情.
The cleanest solution to this problem, is to create a custom layout (we've discussed in the comments how Romi's solution will eventually cause too many problems). However, this is usually not an easy thing to do.
我将向您提供此自定义布局可能是什么样子的粗略草图,以便您可以将其用作起点来创建完全满足您需求的布局.要创建自定义布局,您必须子类化 BaseLayout
并覆盖和实现其 updateDisplayList
和 measure
方法.
I will give you a rough sketch of what this custom layout might look like, so you can use it as a starting point to create one that does exactly what you need.
To create a custom layout, you must subclass BaseLayout
and override and implement its updateDisplayList
and measure
methods.
为了让事情更简单(并且为了不在这里转储 500 行代码),我在这个例子中使用了一些硬编码变量.它假设总是有两列,第一个项目总是 200x200 像素,其他项目总是 100x100 像素.没有horizontalGap 或verticalGap.
结果当然是您可以将此自定义布局(就像现在一样)仅用于此特定列表和这些特定 ItemRenderer.如果您希望它更通用,则必须进行更多计算.
To make things easier (and in order not to dump 500 lines of code in here), I used some hardcoded variables for this example. It assumes there will always be two columns, the first item will always be 200x200 px, and the other items will always be 100x100 px. There is no horizontalGap or verticalGap.
The consequence is of course that you can use this custom layout (as it is now) only for this specific List and these specific ItemRenderers. If you want it to be more generic, you'll have to do a lot more calculations.
但现在是代码:
public class MyCustomLayout extends LayoutBase {
//hardcoded variables
private var columnCount:int = 2;
private var bigTileWidth:Number = 200;
private var bigTileHeight:Number = 200;
private var smallTileWidth:Number = 100;
private var smallTileHeight:Number = 100;
override public function updateDisplayList(width:Number, height:Number):void {
var layoutTarget:GroupBase = target;
if (!layoutTarget) return;
var numElements:int = layoutTarget.numElements;
if (!numElements) return;
//position and size the first element
var el:ILayoutElement = useVirtualLayout ?
layoutTarget.getVirtualElementAt(0) : layoutTarget.getElementAt(0);
el.setLayoutBoundsSize(bigTileWidth, bigTileHeight);
el.setLayoutBoundsPosition(0, 0);
//position & size the other elements in 2 columns below the 1st element
for (var i:int=1; i<numElements; i++) {
var x:Number = smallTileWidth * ((i-1) % 2);
var y:Number = smallTileHeight * Math.floor((i-1) / 2) + bigTileHeight;
el = useVirtualLayout ?
layoutTarget.getVirtualElementAt(i) :
layoutTarget.getElementAt(i);
el.setLayoutBoundsSize(smallTileWidth, smallTileHeight);
el.setLayoutBoundsPosition(x, y);
}
//set the content size (necessary for scrolling)
layoutTarget.setContentSize(
layoutTarget.measuredWidth, layoutTarget.measuredHeight
);
}
override public function measure():void {
var layoutTarget:GroupBase = target;
if (!layoutTarget) return;
var rowCount:int = Math.ceil((layoutTarget.numElements - 1) / 2);
//measure the total width and height
layoutTarget.measuredWidth = layoutTarget.measuredMinWidth =
Math.max(smallTileWidth * columnCount, bigTileWidth);
layoutTarget.measuredHeight = layoutTarget.measuredMinHeight =
bigTileHeight + smallTileHeight * rowCount;
}
}
你可以这样使用它:
<s:List dataProvider="{dp}" height="300">
<s:layout>
<l:MyCustomLayout />
</s:layout>
</s:List>
这篇关于具有不同列数的列表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!