1 Reply Latest reply on Jan 15, 2011 2:43 PM by Shongrunden

    Flex List ItemRenderer : Change States from parent ?

    dragovianDesign

      Hai there,

       

      So i created a list that uses an arrayCollection as dataProvider and an itemRenderer with 2 states : LabelState and ProgressState, the labelState is the start state and shows a Filename, the progressState is the state i need to change to when i press a "Start Upload" Button.

       

      This is the itemrenderer :

       

      <?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" currentState="LabelState" width="800">

      <s:states>

      <s:State name="LabelState" />

      <s:State name="ProgressState" />

      </s:states>

      <fx:Declarations>

      <!-- Place non-visual elements (e.g., services, value objects) here -->

      </fx:Declarations>

      <fx:Script>

      <![CDATA[

      public function changeState():void

      {

      trace("changing state for " + label_field.text);

      this.currentState = "ProgressState";

      trace(this.currentState);

      }

      ]]>

      </fx:Script>

      <s:Label name="label_field" paddingLeft="10" maxHeight="40" paddingTop="10" paddingBottom="10" id="label_field" width="800" color="#333333" includeIn="LabelState" text="{data.label}"/>

      <mx:ProgressBar id="progress_field" left="3" top="3" bottom="3" mode="manual" chromeColor="#0096FF" includeIn="ProgressState" textAlign="center" labelPlacement="center" maximum="100" color="#FFFFFF" right="3"/>

      </s:ItemRenderer>

       

      This is the code for the List :
      <s:List keyUp="lst_selected_files_keyUpHandler(event)" skinClass="styles.skins.ListSkinNoHorizontal"
      borderVisible="false"
      contentBackgroundColor="#c9c9c9" contentBackgroundAlpha="1"
      id="lst_selected_files"
      width="100%" height="100%"
      alternatingItemColors="[#EAEAEA,#FAFAFA]" color="#000000"
      itemRenderer="components.ProgressLabel" dataProvider="{arr_items}" />
      <components:RemoveBar nr_of_items="{arr_items.length}" id="cmp_removeBar" hermesRYA="cmp_removeBar_hermesRYAHandler(event)" bottom="-35" width="100%" height="35" />
      This is the function that changes the states for the current "to be uploaded file":
      protected function uploadNextFile():void
      {
      if(uploadingFile!=null) uploadingFile==null;
      popup = null;
      popup = new ProgressPanel();
      lst_selected_files.selectedIndex = currentUploadNr;
      current_progressItem = lst_selected_files.dataGroup.getElementAt(currentUploadNr) as ProgressLabel;
      current_progressItem.changeState();
      lst_selected_files.validateNow();

      For some reason the states change ... but the elements aren't visually updated, ... meaning that i still see the label and the progressbar isn't visible :/
      anyone ?
        • 1. Re: Flex List ItemRenderer : Change States from parent ?
          Shongrunden Adobe Employee

          This seems to work for me:

           

          <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" >

           

              <s:controlBarContent>

                  <s:Button label="test" click="(list1.dataGroup.getElementAt(0) as Object).test()" />

              </s:controlBarContent>

           

              <s:List id="list1">

                  <s:dataProvider>

                      <s:ArrayList>

                          <fx:Array>

                              [0,1,2]

                          </fx:Array>

                      </s:ArrayList>

                  </s:dataProvider>

                  <s:itemRenderer>

                      <fx:Component>

                          <s:ItemRenderer>

                              <fx:Script>

                                  <![CDATA[

                                      public function test():void {

                                          currentState = 'state2';

                                      }

                                  ]]>

                              </fx:Script>

           

                              <s:states>

                                  <s:State name="state1" />

                                  <s:State name="state2" />

                              </s:states>

           

                              <s:Rect width="50" height="50">

                                 <s:fill>

                                     <s:SolidColor color.state1="red" color.state2="green" />

                                 </s:fill>

                              </s:Rect>

           

                              <mx:ProgressBar includeIn="state2" />

                          </s:ItemRenderer>

                      </fx:Component>

                  </s:itemRenderer>

              </s:List>

           

          </s:Application>

           

          You will probably want to override getCurrentRendererState() to do this properly tho.  This post demonstrates how to use DataRenderer instead if you would rather: http://flexponential.com/2010/02/07/using-datarenderer-to-add-custom-states-to-a-spark-lis t-renderer/

           

          In general you shouldn't interact with the renderers of a List directly (via getElementAt), but rather by changing the data in the List and building an ItemRenderer that reacts to those changes.  So it would be better if you did something like list1.dataProvider.getItemAt(0).changeState = true and then in your renderer override the data setter to change the state if that variable is set.