Actionscript에서 ItemRenderer 사용하기.


ItemRenderer는.. List나 Datagrid 등에서 데이터를 다른식으로 가공하거나 다르게 보이고자 할때 사용합니다.
아이템렌더러의 사용법은 아래링크에서 볼수 있습니다.

검쉰님블로그        :  http://blog.flashplatform.kr/tag/ItemRenderer
준이아빠님 블로그 :  http://kkh1030.blogspot.com/2008/01/datagrid-itemrenderer.html
옥상훈님 블로그    :  http://okgosu.tistory.com/276

하지만 이 글의 요지는 Actionscript에서 ItemRenderer 를 설정할 때 입니다.

mxml 에서는 itemRender="package.ClassName" 이런식으로 하면 아무문제 없이 사용이 가능합니다.
하지만 script에서는 저 방식을 사용하지 못합니다.
저렇게 하면 IFactory로 변환에러가 발생합니다.




.mxml
itemRender="mx.containers.VBox"   == 성공

.as
itemRender="mx.containers.VBox"   == 에러
* 이해하기 쉽게 Render는 VBox를 사용하겠습니다.

API 를 살펴보니 아래와같이 나와있습니다.
public function set itemRenderer(value:IFactory ):void
IFactory 를 넘겨야하는군요.. mxml에서는 자동으로 해주면서..

해결법은 바로 mx.core.ClassFactory 클래스를 이용하면 됩니다.
itemRender = new ClassFactory(VBox);


갑자기 등장한 ClassFactory의 구조는 아래와 같습니다.
public class ClassFactory implements IFactory 
IFactory 를 구현하였습니다

 
public function ClassFactory(generator:Class = null)
생성자에서 클래스를 매개변수로 받습니다.

public function newInstance():*
 {
  var instance:Object = new generator();
        if (properties != null)
        {
         for (var p:String in properties)
   {
          instance[p] = properties[p];
   }
        }
        return instance;
 }
구현하는 newInstance메소드에서 해당 클래스를 생성하고 반환합니다.
생각보다 간단하네요 ㅎㅎ

아래와 같이 properties라는 프로퍼티를 사용하면 해당 클래스 속성에 값도 설정할수 있습니다.
var cf:ClassFactory = new ClassFactory(VBox);
var param:Object;
param["width"] = 30;
param["alpha"] = 0.5;
cf.properties = param;
xxx.itemRender = cf;




또는 ClassFactory 를 사용하지 않고 직접 자신의 Render클래스에서 IFactory를 구현하면 됩니다.
 
(IListItemRenderer는 IFactory만 구현해놓으니깐 에러가 발생해서 추가해놨습니다. 이미 상위에서 구현해놓은 상태여서 따로 구현할것은 없습니다.)


public class CustomItemRenderer extends UIComponent implements IFactory, IListItemRenderer{
  private var _data:Object;
  private var dataChagne:Boolean;

  public function newInstance():*{
   return new CustomItemRenderer ();
  }

  override protected function commitProperties():void{
   super.commitProperties();
   if(this.dataChagne){
    this.dataChagne = false;

    }
   }
  }

  public function get data():Object
  {
   return _data ;
  }

  public function set data(value:Object):void{
   if(this._data == value) return;
   this._data = value;
   this.dataChagne = true;
   this.invalidateProperties();
  }
}
이런식으로 해서 사용할때에는 아래와 같이 사용하면 ClassFactory없이 가능합니다.
xxx.itemRenderer = new CustomItemRenderer();

하지만 별 의미는 없습니다. -_-;;ㅋ
그냥 ClassFactory클래스를 이용하는게 편리합니다 ㅎㅎ