8 Replies Latest reply on Feb 5, 2011 12:22 PM by Shongrunden

    Spark List: itemRenderer called twice for first item

    Adnan Doric Level 1

      Hello all,

       

      There is an issue with itemRenderer in the spark List, it is called twice for the first item, and only for the first item :

       

      Application :

      <?xml version="1.0" encoding="utf-8"?>
      <s:Application xmlns:s="library://ns.adobe.com/flex/spark"
          xmlns:fx="http://ns.adobe.com/mxml/2009"
          xmlns:mx="library://ns.adobe.com/flex/mx"
          creationComplete="creationCompleteHandler(event)"
          >
         
          <fx:Script>
              <![CDATA[
                  import mx.collections.ArrayCollection;
                  import mx.events.FlexEvent;

                  protected function creationCompleteHandler(event:FlexEvent):void
                  {
                      var ac:ArrayCollection = new ArrayCollection();
                      ac.addItem({id:0});
                      ac.addItem({id:1});
                      list.dataProvider = ac;
                  }

              ]]>
          </fx:Script>
         
          <s:List id="list" itemRenderer="Renderer" />
      </s:Application>

       

      Renderer:

      <?xml version="1.0" encoding="utf-8"?>
      <s:ItemRenderer xmlns:s="library://ns.adobe.com/flex/spark"
          xmlns:fx="http://ns.adobe.com/mxml/2009"
          >
         
          <fx:Script>
              <![CDATA[
                  override public function set data(value:Object):void
                  {
                      if (value != null)
                      {
                          super.data = value;
                          trace("data.id = " + data.id);
                          lbl.text = data.id;
                      }
                  }
              ]]>
          </fx:Script>
         
          <s:Label id="lbl" />
         
      </s:ItemRenderer>

       

      The output in the console is (there is one extra data.id = 0):

      data.id = 0
      data.id = 0
      data.id = 1

       

      I have a big problem in real world application because of this behavior, should I fill a bug or there is some kind of workaround please ?

       

      Thank you in advance,

      Adnan

        • 1. Re: Spark List: itemRenderer called twice for first item
          Peter deHaan Level 4

          I wouldnt expect that either, unless it's creating the first item in the data provider and using it as a typical item renderer for sizing or something like that.

           

          I suggest filing a bug at http://bugs.adobe.com/flex/ and somebody from Adobe will have a look.

           

          Thanks,

          Peter

          • 3. Re: Spark List: itemRenderer called twice for first item
            Shongrunden Adobe Employee

            This is working as expected.  The List uses a typicalItem to create a typicalLayoutElement which describes the visual size of the ItemRenderer for an item.  This is to support virtual layout which is on by default in List.  If you don't define a typicalItem then the List will use the first item in the dataProvider as the typicalItem.

             

            You might want to do something like this instead:

             

            <s:List id="list" typicalItem="{{id:-1}}">

             

            Or if you don't want the benefits of virtual layout you could just turn it off:

             

            <s:List id="list" useVirtualLayout="false">
            • 4. Re: Spark List: itemRenderer called twice for first item
              Adnan Doric Level 1

              Thank you, that seems to work, I will test it

              • 5. Re: Spark List: itemRenderer called twice for first item
                theMadPenguin Level 1

                Hi Shongrunden,

                Are you sure this is working as expected? Setting useVirtualLayout to false will have unwanted effects. For example, try to enable drag move in your list, notice that item renderers will get created but not recycled, resulting in repeated rows in your list. That cannot be expected behavior.

                Thanks in advance,

                 

                ~ TheMadPenguin

                • 6. Re: Spark List: itemRenderer called twice for first item
                  Shongrunden Adobe Employee

                  The default List behavior is to create new items when dragging and dropping within the same List (this is the same behavior regardless of virtual layout), for example:

                   

                  <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"

                                 xmlns:s="library://ns.adobe.com/flex/spark"> 

                      <!-- useVirtualLayout=true acts the same way -->

                      <s:List dragEnabled="true" dropEnabled="true" useVirtualLayout="false">

                          <s:dataProvider>

                              <s:ArrayList>

                                  <fx:String>one</fx:String>

                                  <fx:String>two</fx:String>

                                  <fx:String>three</fx:String>

                                  <fx:String>four</fx:String>

                              </s:ArrayList>

                          </s:dataProvider>

                      </s:List>

                   

                  </s:Application>

                   

                  If you are looking to drag things within a List without copying you will need to set the dragMoveEnabled flag to true, for example:

                  <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"

                                 xmlns:s="library://ns.adobe.com/flex/spark"> 

                   

                      <s:List dragEnabled="true" dropEnabled="true" dragMoveEnabled="true" useVirtualLayout="false">

                          <s:dataProvider>

                              <s:ArrayList>

                                  <fx:String>one</fx:String>

                                  <fx:String>two</fx:String>

                                  <fx:String>three</fx:String>

                                  <fx:String>four</fx:String>

                              </s:ArrayList>

                          </s:dataProvider>

                      </s:List>

                   

                  </s:Application>

                   

                  Is this what you are running into?  If not can you post a small example like this that demonstrates it?

                   

                   

                  If you are changing or refreshing the dataProvider then you might be running into this bug:

                  http://bugs.adobe.com/jira/browse/SDK-28709

                   

                  I recently filed an enhancement to have itemIndex be -1 when dealing with the typicalItem that way your renderer can tell easily whether you are rendering the typicalItem or a normal item:

                  http://bugs.adobe.com/jira/browse/SDK-29220

                   

                  Please vote and/or comment on those bugs if they would be useful to you.

                  • 7. Re: Spark List: itemRenderer called twice for first item
                    theMadPenguin Level 1

                    Hi Shongrunden,

                    I found what the issue was but I am not sure I understand what is happening. The data associated to my item renderer has a property that is bound to the length of the data provider:

                     

                    myProperty = dataProvider.length > 1;

                     

                    When I was able to see the issue (item renderers not getting removed during a reorder) I was resetting the variable by listening to changes in dataProvider via a CollectionChange event. When having two items a reorder caused the variable to be set to false then to true (this would only fail with two items which is of course the number of items I was testing with). This somehow affects the destruction of item renderers. Binding to the length of the dataProvider via BindingUtils would have the same effect.

                     

                    The solution was to wait for the UpdateComplete event fired by the list before setting myProperty again... If you are interested in reproducing this I will provide a sample app, otherwise I can live with the workaround.

                    Thanks for your time,


                    ~ TheMadPenguin

                    • 8. Re: Spark List: itemRenderer called twice for first item
                      Shongrunden Adobe Employee

                      Interesting.  That would be great if you can provide a sample application so I can investigate what is going on.