0

flex でアイテムレンダラーのスパークリストを作成しましたが、その後ではなく、リストに新しい行を追加するときに関数を呼び出したいです。レンダリングされたリストでデータオブジェクトを取得しています。リストに表示されるデータのタイプを取得しています。テキストでも画像でも。そのため、リストに新しいデータを追加するときに、レンダリングされたリストで関数を呼び出して、受信したデータのタイプをチェックし、画像要素またはテキスト要素を作成して追加します。したがって、主な問題は、データの追加時に呼び出される関数を取得する方法です。datachange や added などのイベントを試してみましたが、リストをスクロールすると関数を何度も呼び出し続けますが、病棟後ではなく、データの追加時にのみ関数を呼び出す必要があります。以下はレンダラー リスト コードです。おそらく、私がやろうとしていることをよりよく理解できるでしょう。

<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="test_add()">

    <fx:Script>
        <![CDATA[
            import mx.controls.Alert;
            public function test_add() : void {
                Alert.show("type="+data.msg_type);      
                if(data.msg_type=="text"){
                    //code to create and add new text element to list_row//
                }
                if(data.msg_type=="image"){
                    //code to create and add new image element to list_row//
                }
            }

        ]]>
    </fx:Script>

    <s:Group id="list_row" width="100%" verticalAlign="middle"  verticalCenter="0">

    </s:Group>
</s:ItemRenderer>

どんな助けでも大歓迎です。ありがとう

4

1 に答える 1

1

あなたが示したコードからわかる限り、問題の最も簡単な解決策は、テキストをレンダリングするものと画像をレンダリングするものという 2 つの別々の ItemRenderer を使用することです。の代わりにSkinnableDataContainer#itemRendererFunctionプロパティを使用してこれを行うことができますitemRenderer

新しいプロパティを持つリスト:

<s:List id="myList" dataProvider="{dp}" 
        itemRendererFunction="getItemRenderer" />

適切な ItemRenderer のファクトリを返す関数。

private function getItemRenderer(item:Object):IFactory {
    if (item.msg_type == "text") 
        return new ClassFactory(MyTextItemRenderer);
    if (item.msg_type == "image") 
        return new ClassFactory(MyImageItemRenderer);
}

これら 2 つの異なる ItemRenderer で、必要に応じてデータを表示できます。


編集:dataChangeスクロールするたびにイベントが発生しても問題ない理由。

実際、あなたが説明したように、あなたのアプローチには何も問題はありませんが、このitemRendererFunctionアプローチにより懸念事項をより適切に分離できると私は主張します。List#useVirtualLayoutプロパティを に設定するだけで、不要な動作をオフにできると言えますfalse

<s:List id="myList" dataProvider="{dp}" 
        itemRenderer="myItemRenderer" useVirtualLayout="false" />

これはあなたが求めていることを実行しますが (つまり、ItemRenderers を 1 回だけ作成します)、それは良いアドバイスではありません。このプロパティがtrueデフォルトで設定されているのには十分な理由があります。

仮想レイアウトを使用すると、アイテム レンダラーは必要なときにのみ作成されます。つまり、ビューに表示され、ユーザーに表示する必要がある場合です。これにより、パフォーマンスを損なうことなく何千ものアイテムをロードできます。

1000 個の値オブジェクトをロードするとします。これはメモリや CPU をあまり消費しません。しかし今、あなたはそれらをレンダリングしたいと思っています。仮想レイアウトを使用しない場合、それらすべてに対してアイテム レンダラーが事前に作成されます。つまり、何千ものグラフィック要素と何千ものイベント リスナーが作成されます (正確な数は設定によって異なります)。これにより、低速のコンピューターでパフォーマンスが低下します。

仮想レイアウトのみを使用する場合、たとえば、10 個のアイテム レンダラーが一度に作成されます。ユーザーが下にスクロールすると、次の 10 個が作成され、ビューから消えたばかりのものは削除され、最終的にガベージ コレクションが行われます。ご覧のとおり、最初はパフォーマンスに悪いと思っていたものも、実際には非常に良いものです。

ですから、私が今言ったことをしないことをお勧めします。おそらく、リストに非常に限られた数のアイテムしかないことがわかっている状況がない限り. 次に、仮想レイアウトを使用しないことを検討できます。

于 2012-02-05T14:15:40.287 に答える