如何在 Spark List 中正确显示动态大小的项目?
Posted
技术标签:
【中文标题】如何在 Spark List 中正确显示动态大小的项目?【英文标题】:How to correctly display item with dynamic size in Spark List? 【发布时间】:2013-04-08 08:53:06 【问题描述】:我在 Spark 列表中显示一些动态数据时遇到问题。
我需要在列表中显示来自数据提供者的一些文本。该列表应该显示所有没有任何滚动条的文本,并且文本可以像 html 一样格式化。
我无法控制列表本身的大小。
也就是说,我需要根据要显示的数据显示具有动态大小的项目。由于渲染项目的宽度应该是列表本身的宽度,我想要的是不同的项目以动态高度显示。
到目前为止,我尝试通过 TextArea
组件使用自定义 ItemRenderer
。下面是一个总结问题的示例应用程序:
<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
minHeight="400">
<s:List top="20" right="20" bottom="20" left="20" borderVisible="true"
itemRenderer="CustomItemRenderer" horizontalScrollPolicy="off">
<s:layout>
<s:VerticalLayout gap="0" horizontalAlign="justify"/>
</s:layout>
<s:dataProvider>
<s:ArrayCollection>
<fx:Object time="00:01:23" level="DEBUG" message="This is a short log message"/>
<fx:Object time="00:02:34" level="DEBUG" message="This is a not so short log message"/>
<fx:Object time="00:03:45" level="DEBUG" message="This is not a short log message that won't display correctly on one line"/>
<fx:Object time="00:04:56" level="DEBUG" message="This is a long message that will require two lines to be displayed correctly"/>
<fx:Object time="00:05:23" level="DEBUG" message="Short again"/>
<fx:Object time="00:06:34" level="DEBUG" message="Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."/>
</s:ArrayCollection>
</s:dataProvider>
</s:List>
</s:Application>
使用我的自定义项目渲染器的代码CustomItemRenderer.mxml
:
<?xml version="1.0" encoding="utf-8"?>
<s:ItemRenderer xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
autoDrawBackground="true"
dataChange="handleDataChange(event)">
<s:states>
<s:State name="normal" />
<s:State name="hovered" />
<s:State name="selected" />
</s:states>
<fx:Script>
<![CDATA[
import flashx.textLayout.elements.ParagraphElement;
import flashx.textLayout.elements.SpanElement;
import flashx.textLayout.elements.TextFlow;
import mx.events.FlexEvent;
protected function handleDataChange(event:FlexEvent):void
var flow:TextFlow = new TextFlow();
var timeSpan:SpanElement = new SpanElement();
timeSpan.text = "[" + data.time + "] ";
timeSpan.fontFamily = "_mono";
var levelSpan:SpanElement = new SpanElement();
levelSpan.text = data.level + ": ";
levelSpan.fontWeight = "bold";
var messageSpan:SpanElement = new SpanElement();
messageSpan.text = data.message;
var paragraph:ParagraphElement = new ParagraphElement();
paragraph.addChild(timeSpan);
paragraph.addChild(levelSpan);
paragraph.addChild(messageSpan);
flow.addChild(paragraph);
mainText.textFlow = flow;
]]>
</fx:Script>
<s:BorderContainer id="container"
borderVisible="false" borderWeight="0"
dropShadowVisible="false">
<s:layout>
<s:BasicLayout />
</s:layout>
<s:TextArea id="mainText" heightInLines="NaN"
borderVisible="false" selectable="true" editable="false">
</s:TextArea>
</s:BorderContainer>
</s:ItemRenderer>
我尝试将我的 TextArea 组件的 heightInLines
属性设置为 NaN
,正如 here 所解释的那样,以使 textarea 自身自动调整。
我也尝试将容器的高度设置为等于 textArea 的高度,但是在我设置 TextFlow
之后这个高度为 0,如果我等待调整大小事件,列表不会显示也正确。
我尝试将布局的horizontalAlign
属性设置为justify
,而不是contentJustify
,因为我阅读了here。
有时,在我单击某个项目之前,列表中不会显示任何内容。这将只显示这个项目,我必须对每个项目做同样的事情。
我真的不明白发生了什么,在尝试了很多不同的事情后开始迷失方向。 任何帮助将不胜感激...
【问题讨论】:
【参考方案1】:尝试设置ItemRenderer的宽高。您的代码示例:
<s:ItemRenderer xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
autoDrawBackground="true"
dataChange="handleDataChange(event)"
>
附言 也许为了获得更好的列表性能,您可以尝试将 TextFlow 创建移出 ItemRenderer。例如,创建 textFlows 并将它们放入 list 的 dataprovider 中,然后从 ItemRenderer 的数据值中使用 textflow:
mainText.textFlow = data.flow;
【讨论】:
【参考方案2】:为了正确显示列表,我对代码进行了以下更改:
首先,由于列表项具有动态大小,我们必须告诉编译器不要在列表上使用虚拟布局:
<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
minHeight="400">
<s:List top="20" right="20" bottom="20" left="20" borderVisible="true"
useVirtualLayout="false"
itemRenderer="CustomItemRenderer" horizontalScrollPolicy="off">
...
</s:List>
</s:Application>
然后,正如 Nemi 所说,我们需要设置项目渲染器的宽度(注意这里不必指定高度):
<?xml version="1.0" encoding="utf-8"?>
<s:ItemRenderer xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
autoDrawBackground="true"
dataChange="handleDataChange(event)">
...
</s:ItemRenderer>
【讨论】:
以上是关于如何在 Spark List 中正确显示动态大小的项目?的主要内容,如果未能解决你的问题,请参考以下文章
approxQuantile 在 Spark (Scala) 中给出不正确的中位数?
如何在具有动态大小的单元格的 UICollectionViewFlowLayout 子类上正确设置节插入