1 Reply Latest reply on Aug 17, 2010 10:41 AM by afarber

    Scaling up items when the parent List becomes wider

    afarber

      Hello,

       

       

      I have an itemRenderer for a List, displaying avatars for users in  chat rooms - up to 3 of them. It works ok, but since the List itself is  inside of a HDividedBox and its width can be changed, I would like to  detect this event and let my itemRenderer to display bigger avatars (by  increasing their scaleX, scaleY? or maybe there is a better way...)

       

       

      My problem is that I don't know how to increase the rowHeight of the parent List and thus the tops and bottoms of the List items are being cut off.

       

       

      I've prepared a reduced test case which demonstrates my problem (I've replaced avatars by 100x100 Buttons) -

       

       

      TestCase.mxml:

       

      <?xml version="1.0" encoding="utf-8"?>
      <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">
         
      <mx:HDividedBox width="100%" height="100%">
             
      <mx:List id="myList" width="40%" height="100%"
                 
      alternatingItemColors="[0xCCCCCC, 0xFFFFFF]"
                 
      dataProvider="{['a;b;c', '1;2;3', '4;5', 'd', '6;7;8']}"
                 
      itemRenderer="RowRenderer"/>
             
      <mx:Label text="&lt;-- Resize the list" width="60%"/>
         
      </mx:HDividedBox>
      </mx:Application>

       

      RowRenderer.mxml:

       

       

      <?xml version="1.0" encoding="utf-8"?>
      <mx:Canvas xmlns:mx="http://www.adobe.com/2006/mxml"
         
      width="100%" height="100%"
         
      verticalScrollPolicy="off" horizontalScrollPolicy="off">

         
      <mx:Script>
          <![CDATA[
          [Bindable]
          private var _scale:Number = 0.8;

          override public function set data(obj:Object):void {
              var i:uint;

              super.data = obj;

              for (i = 0; i < _btn.length; i++)
                  _btn[i].visible = false;

              if (obj != null) {
                  var str:String = String(obj);
                  var labels:Array = str.split(/;/);
                  for (i = 0; i < _btn.length && i < labels.length; i++) {
                      _btn[i].label = labels[i];
                      _btn[i].visible = true;
                  }
              }
          }

          override protected function measure():void {
              super.measure();

              measuredWidth = 3 * 100 * _scale;
              measuredHeight = 100 * _scale;

              measuredMinWidth = 3 * 50;
              measuredMinHeight = 50;
          }

          override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void {
              super.updateDisplayList(unscaledWidth, unscaledHeight);
              trace(unscaledWidth + ' x ' + unscaledHeight);

              _scale = (unscaledWidth > 3 * 100 ? 1.2 : 0.8);

              // XXX how to set the list rowHeight=100*_scale here?
          }
          ]]>
         
      </mx:Script>

         
      <mx:HBox width="100%" horizontalAlign="center">
             
      <mx:Repeater id="_rpt" dataProvider="{[0, 1, 2]}">
                 
      <mx:Button id="_btn" width="100" height="100" fontSize="24"
                   
      textAlign="center" scaleX="{_scale}" scaleY="{_scale}"/>
             
      </mx:Repeater>
         
      </mx:HBox>

      </mx:Canvas>

       

      Screenshot demonstrating my problem (buttons are cut off):

       

      row.png

       

       

      I've also tried accessing parent.rowHeight and (parent as List).rowHeight from my custom itemRenderer, but they give me compile and runtime errors

       

       

      Thank you

      Alex

        • 1. Re: Scaling up items when the parent List becomes wider
          afarber Level 1

          Hello again,

           

          I thought I've found a solution by using the List's resize event to change the size of its items, but while it works for the simple test case listed below, it goes into endless loop in my real app with more complex layout and I see the traces:

           

          resize list: 0 -> 480
          resize list: 480 -> 480
          resize list: 480 -> 464
          resize list: 464 -> 464
          resize list: 464 -> 480
          resize list: 480 -> 480
          resize list: 480 -> 464
          resize list: 464 -> 464

          ...

           

          TestCase.mxml:
          <?xml version="1.0" encoding="utf-8"?>
          <mx:Application xmlns:mx="
          http://www.adobe.com/2006/mxml">
          <mx:Script>
              <![CDATA[
              import mx.events.*;
              private function resizeHandler(event:ResizeEvent):void {
          var list:List = event.target as List;
          trace(event.oldWidth + ' -> ' + list.width);
          list.rowHeight = list.width / 3;
          RowRenderer._scale = list.rowHeight / (100 + 20);
              }
              ]]>
              </mx:Script>
              <mx:HDividedBox width="100%" height="100%">
              <mx:List id="myList" width="40%" height="100%"
                alternatingItemColors="[0xCCCCCC, 0xFFFFFF]"
                dataProvider="{['a;b;c', '1;2;3', '4;5', 'd', '6;7;8']}"
                itemRenderer="RowRenderer" resize="resizeHandler(event)"/>
              <mx:Label text="&lt;-- Resize the list" width="60%"/>
              </mx:HDividedBox>
          </mx:Application>
          RowRenderer.mxml:
          <?xml version="1.0" encoding="utf-8"?>
          <mx:Canvas xmlns:mx="
          http://www.adobe.com/2006/mxml"
            width="100%" height="100%"
            verticalScrollPolicy="off" horizontalScrollPolicy="off">
              <mx:Script>
              <![CDATA[
              import mx.controls.List;
              [Bindable]
              public static var _scale:Number = 1.0;
              override public function set data(obj:Object):void {
          var i:uint;
          super.data = obj;
          for (i = 0; i < _btn.length; i++)
               _btn[i].visible = false;
          if (obj != null) {
               var str:String = String(obj);
               var labels:Array = str.split(/;/);
               for (i = 0; i < _btn.length && i < labels.length; i++) {
            _btn[i].label = labels[i];
            _btn[i].visible = true;
               }
          }
              }
              ]]>
              </mx:Script>
              <mx:HBox width="100%" horizontalAlign="center">
          <mx:Repeater id="_rpt" dataProvider="{[0, 1, 2]}">
          <mx:Button id="_btn" width="100" height="100" fontSize="24"
             textAlign="center" scaleX="{_scale}" scaleY="{_scale}"/>
          </mx:Repeater>
              </mx:HBox>
          </mx:Canvas>
          Any hints please? I think I'm missing something minor
          Alex