如何在Spark List中正确显示动态大小的项目?

时间:2013-04-16 04:24:46

标签: list flex flex-spark

我在Spark列表中显示一些动态数据时出现问题。

我需要在列表中显示来自数据提供者的一些文本。该列表应显示所有文本,不带任何滚动条,文本可以格式化为HTML格式。

我无法控制列表本身的大小。

也就是说,我需要根据要显示的数据显示动态大小的项目。由于渲染项目的宽度应该是列表本身的宽度,我想要的是不同的项目显示动态高度。

到目前为止,我尝试使用ItemRenderer组件使用自定义TextArea。这是一个总结问题的示例应用程序:

<?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"
               width="450" 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" width="100%"
                       borderVisible="false" borderWeight="0"
                       dropShadowVisible="false">
        <s:layout>
            <s:BasicLayout />
        </s:layout>

        <s:TextArea id="mainText" width="100%" heightInLines="{NaN}"
                    borderVisible="false" selectable="true" editable="false">
        </s:TextArea>
    </s:BorderContainer>
</s:ItemRenderer>

我尝试将TextArea组件的heightInLines属性设置为NaN,如here所述,让textarea自动重新设置。

我还尝试将容器的高度设置为等于textArea的高度,但是在设置TextFlow之后此高度为0,如果我等待调整大小事件,则列表不会t正确显示。

在我阅读here时,我尝试将布局的horizontalAlign属性设置为justify而不是contentJustify

有时,在点击某个项目之前,列表中不会显示任何内容。然后,这将只显示此项目,我将不得不对每个项目执行相同的操作。

我真的不明白发生了什么,并在尝试了很多不同的事情后开始迷路。 任何帮助将不胜感激......

2 个答案:

答案 0 :(得分:0)

尝试设置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)"

        width="100%" height="100%">

P.S。 也许为了获得更好的列表性能,您可以尝试将TextFlow创建移出ItemRenderer。例如,创建textFlows并将它们放在list的dataprovider中,然后使用ItemRenderer的数据值中的textflow:

mainText.textFlow = data.flow;

答案 1 :(得分:0)

为了正确显示列表,我对代码进行了以下更改:

首先,由于列表项具有动态大小,我们必须告诉编译器不要在列表中使用虚拟布局:

<?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"
               width="450" 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"
                width="100%"
                dataChange="handleDataChange(event)">
    ...
</s:ItemRenderer>