1. I would use a RadioButton in the item-renderer for a clear selection.
2. You can dispatch bubbling events from within an item-renderer, so the
event listener would be defined on the list itself.
3. An item-renderer shouldn't access the topLevelApplication unless there's
a REALLY good reason (which you don't seem to have).
4. You can define the first tag of the item-renderer as VGroup and then you
won't need the internal VGroup.
For better performance one must always try to use the minimal number of
components needed for accomplishing the desired layout.

Good luck,
Evyatar


On Mon, Jun 10, 2013 at 8:30 AM, Sumudu Chinthaka <[email protected]> wrote:

> thanks Alex
>
> what im actually trying to do is implement a meal menu
> passenger can only select one meal at a time
> so i have a custom component that i have added to itemrenderer which fires
> events when quantity change happen
> whenever quntity is changed i want to reset all the other component values
> because passenger should be able to select only one meal
>
> please find the code below
>
>
> ShowMeals View with list of avalable meals
>
> <?xml version="1.0" encoding="utf-8"?>
> <s:View xmlns:fx="http://ns.adobe.com/mxml/2009";
>    xmlns:s="library://ns.adobe.com/flex/spark"
> creationComplete="init(event)">
> <fx:Script>
>  <![CDATA[
> import com.isa.mobile.data.Globals;
>  import mx.collections.ArrayCollection;
> import mx.core.FlexGlobals;
> import mx.events.FlexEvent;
>  import mx.events.ResizeEvent;
> import mx.resources.IResourceManager;
>  [Bindable]
> *private var meals:ArrayCollection;*
>  [Bindable]
> private var resMgr:IResourceManager;
>  [Bindable]
> private var defHeight:Number;
>  protected function init(event:FlexEvent):void
> {
> defHeight = Globals.getComponentHeight(Globals.BUTTON_HEIGHT);
>  resMgr = FlexGlobals.topLevelApplication.appResourceManager;
> this.meals = data as ArrayCollection;
>  }
>  protected function confirm_clickHandler(event:MouseEvent):void
>  {
>  }
>  ]]>
> </fx:Script>
>  <fx:Metadata>
> [ResourceBundle("form_resources")]
> </fx:Metadata>
>  <s:Group width="100%" height="100%" verticalCenter="0"
> horizontalCenter="0">
> <s:Rect width="100%" height="100%">
>  <s:fill>
> <s:SolidColor color="0x32373d"/>
> </s:fill>
>  </s:Rect>
> <s:VGroup width="98%" height="98%" verticalCenter="0" horizontalCenter="0">
>  <s:Button
> label="{resMgr.getString('form_resources','app.setMeal.selectMeal')}"
>  skinClass="com.isa.mobile.skins.ViewTitleButtonSkin"
> height="{Globals.getComponentHeight(Globals.TITLE_HEIGHT)}"   width="100%"/>
>  <s:List   width="100%" height="100%" dataProvider="{meals}"
> itemRenderer="com.isa.mobile.renderers.MealsItemRenderer"  >
>  </s:List>
> <s:Button
>  label="{resMgr.getString('form_resources','app.common.confirm')}"
> click="confirm_clickHandler(event)"
> skinClass="com.isa.mobile.skins.ViewSubmitButtonSkin" height="{defHeight}"
> width="100%" />
>  </s:VGroup>
> </s:Group>
> </s:View>
>
>
> *com.isa.mobile.renderers.MealsItemRenderer*
>
> package com.isa.mobile.renderers
> {
>  import com.isa.mobile.data.Globals;
> import com.isa.mobile.events.QuantityComponentEvent;
>  import flash.display.GradientType;
> import flash.display.Loader;
> import flash.events.Event;
>  import flash.events.IOErrorEvent;
> import flash.geom.Matrix;
> import flash.net.URLRequest;
>  import flash.text.TextLineMetrics;
>  import mx.core.FlexGlobals;
>  import mx.effects.Resize;
> import mx.events.FlexEvent;
> import mx.events.ResizeEvent;
>  import mx.rpc.events.ResultEvent;
>  import spark.components.Group;
>  import spark.components.HGroup;
> import spark.components.IconItemRenderer;
> import spark.components.Image;
>  import spark.components.Label;
> import spark.components.LabelItemRenderer;
> import spark.components.VGroup;
>  import spark.primitives.BitmapImage;
>  import views.components.QuantityComponent;
>  public class MealsItemRenderer extends LabelItemRenderer
> {
>   private var loader:Loader;
>  [Embed(source="assets/dpi160/food.png")]
> private var defaultFood_160:Class;
>  [Embed(source="assets/dpi240/food.png")]
> private var defaultFood_240:Class;
>  [Embed(source="assets/dpi320/food.png")]
> private var defaultFood_320:Class;
>  [Bindable]
> private var dpi:Number;
>  private var imageSource:Class;
>  private var foodImage:Image;
>  [Bindable]
>  private var listItemHeight:Number;
>  private var paddingYValue:Number;
>  private var paddingXvalue:Number;
> private var listItemHeadingHeight:Number = 30;
> private var defaultLabelheight:Number;
>  private var imageHeight:Number;
>  private var rowHeadTxt:Label;
>  private var mealDesc:Label;
>  private var qty:QuantityComponent;
>  private var price:Label;
>  private var totalDisplay:Label;
>   private var vg:VGroup;
> private var hGroup_header:HGroup;
>  private var hGroup_1:HGroup;
> private var hGroup_2:HGroup;
>  private var _price:Number;
> private var _isMultipleMealsAllowed:Boolean;
>  private var _qtyChnageEvent:QuantityComponentEvent;
>   public function MealsItemRenderer()
> {
> loader = new Loader();
>  dpi = Globals.getComponentHeight(Globals.DPI);
> *
> FlexGlobals.topLevelApplication.dispatcher.addEventListener(QuantityComponentEvent.QUANTITY_CHANGED,qtyChangeHandler);
> *
>  }
>  override protected function createChildren():void
>  {
> switch(dpi)
> {
> case 160:
>  {
> imageSource = defaultFood_160;
> paddingYValue = 5;
>  paddingXvalue = 10;
> listItemHeadingHeight = 30;
>  defaultLabelheight = 26;
> imageHeight = 50;
> break;
>  }
>  case 240:
> {
>  imageSource = defaultFood_240;
> paddingYValue = 7;
> paddingXvalue = 15;
>  listItemHeadingHeight = 45;
> defaultLabelheight = 39;
> imageHeight = 75;
>  break;
> }
>  case 320:
>  {
> imageSource = defaultFood_320;
> paddingYValue = 10;
>  paddingXvalue = 20;
> listItemHeadingHeight = 60;
>  defaultLabelheight = 52;
> imageHeight = 100;
> break;
>  }
> }
>  rowHeadTxt = new Label();
>  rowHeadTxt.percentWidth = 50;
> mealDesc = new Label();
> mealDesc.percentWidth = 100;
>  totalDisplay = new Label();
> totalDisplay.percentWidth = 50;
>  totalDisplay.height = Globals.getComponentHeight(Globals.LABEL_HEIGHT);
>     totalDisplay.styleName = "totalDisplay";
>  totalDisplay.visible = false;
>  foodImage = new Image();
>  qty = new QuantityComponent().initializeQuantityComponent("Quantity");
> qty.percentWidth = 50;
>  price = new Label();
> price.percentWidth = 50;
>  price.styleName = "price";
>  vg = new VGroup;
>  vg.verticalCenter = 0;
> vg.percentWidth = 100;
>   hGroup_header = new HGroup();
> hGroup_header.percentWidth = 100;
>  hGroup_header.addElement(rowHeadTxt);
> hGroup_header.addElement(price);
>  hGroup_1 = new HGroup();
> hGroup_1.percentWidth = 100;
>  hGroup_1.percentHeight = 30;
>   hGroup_1.addElement(foodImage);
> hGroup_1.addElement(mealDesc);
>  hGroup_2 = new HGroup();
> hGroup_2.percentWidth = 100;
>  hGroup_2.percentHeight = 70;
> hGroup_2.verticalAlign = "top";
>  hGroup_2.addElement(qty);
> hGroup_2.addElement(totalDisplay);
>   vg.addElement(hGroup_1);
> vg.addElement(hGroup_2);
>  addChild(vg);
> addChild(hGroup_header);
>   }
>  *private function qtyChangeHandler(event:QuantityComponentEvent):void{*
> * _qtyChnageEvent = event;*
> * *
> * if(this.qty == event.quantityComponent){*
> * var tot:Number = _price * event.quantity;*
> * totalDisplay.text = "Total : " + tot;*
> * totalDisplay.visible = true;*
> * }else{*
> * if(!_isMultipleMealsAllowed){*
> * qty.setQuantity(0);*
> * totalDisplay.visible = false;*
> * }*
> * } *
> * } *
>  override public function set data(value:Object):void
> {
>  rowHeadTxt.text = value.mealName;
> rowHeadTxt.setStyle("color",0xffffff);
> mealDesc.text = value.mealDescription;
>  loader.load(new URLRequest(encodeURI(value.mealImageLink)));
>
> loader.contentLoaderInfo.addEventListener(Event.COMPLETE,function(e:Event):void{
> foodImage.source = e.currentTarget.content;
>  });
>
> loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR,function(e:Event):void{
>  foodImage.source = new imageSource();
> });
>   //test
> if(_qtyChnageEvent!=null)
> {
>  if(_qtyChnageEvent.quantityComponent != qty){
> this.qty.setQuantity(0);
> }else{
>  this.qty.setQuantity(_qtyChnageEvent.quantity);
> }
>  }
>  if(value.isMultipleMealsAllowed){
> qty.setNoMaxQuantity(true);
>  _isMultipleMealsAllowed = true;
> }else{
> qty.setMaxQuantity(1);
>  _isMultipleMealsAllowed = false;
> }
>  price.text = "Price : "+value.mealCharge;
>  _price = value.mealCharge;
>  var s:TextLineMetrics = mealDesc.measureText(value.mealDescription);
>  var sss:Number = mealDesc.getStyle("lineHeight");
>  listItemHeight = listItemHeadingHeight + paddingYValue + imageHeight
> +paddingYValue + qty.getComponentHeight() + paddingYValue ;
>   var ww:Number =vg.rowHeight;
>   }
>  override protected function layoutContents(unscaledWidth:Number,
> unscaledHeight:Number):void
>  {
> var yPos:Number = paddingYValue + listItemHeadingHeight;
>  setElementSize(hGroup_header,unscaledWidth - (paddingXvalue *
> 2),listItemHeadingHeight - (paddingYValue));
> setElementPosition(hGroup_header,paddingXvalue *
> 2,(listItemHeadingHeight/2) - paddingYValue);
>  setElementSize(vg,unscaledWidth - (paddingXvalue * 4),unscaledHeight);
> setElementPosition(vg,paddingXvalue*2,yPos);
>  /*setElementSize(foodImage,imageHeight,imageHeight);
> setElementPosition(foodImage,paddingXvalue * 2,yPos); */
>  /*setElementSize(mealDesc,unscaledWidth - imageHeight - (paddingXvalue *
> 4),imageHeight/2);
> setElementPosition(mealDesc,paddingXvalue + imageHeight + paddingXvalue +
> paddingXvalue ,yPos);
>  yPos += imageHeight/2;
>  setElementSize(qty,(mealDesc.width/2),qty.getComponentHeight());
>  setElementPosition(qty,paddingXvalue + imageHeight + paddingXvalue +
> paddingXvalue,yPos);*/
>  }
>  override protected function measure():void
> {
>  super.measure();
>  /*measuredHeight = this.listItemHeadingHeight +
> vg.getExplicitOrMeasuredHeight(); /*this.listItemHeight;*/
>  var dd:Number = vg.contentHeight;
> var ddd:Number = vg.height;
>  switch(dpi)
> {
> case 160:
>  {
> measuredHeight = 200;
> break;
> }
>  case 240:
> {
> measuredHeight = 300;
>  break;
> }
>  case 320:
>  {
> measuredHeight = 400;
> break;
> }
>  }
>  }
>  override protected function drawBackground(unscaledWidth:Number,
> unscaledHeight:Number):void
>  {
>  graphics.lineStyle(1,0xcccccc);
>  graphics.beginFill(0xcccccc);
> graphics.drawRoundRect(paddingXvalue, 0, unscaledWidth - (paddingXvalue *
> 2), unscaledHeight - paddingYValue,10,10);
>  graphics.endFill();
>  var ratioArray:Array = [0,100];
>  var backgroundColors:Array = [0x505358, 0x1d2028];
> var matrix2:Matrix = new Matrix();
>  matrix2.createGradientBox(unscaledWidth, listItemHeadingHeight, Math.PI
> / 2, 0, 0);
> graphics.beginGradientFill(GradientType.LINEAR, backgroundColors, [1,1],
> ratioArray, matrix2);
>  graphics.drawRoundRectComplex(paddingXvalue,0 , unscaledWidth -
> (paddingXvalue * 2), listItemHeadingHeight,5,5,0,0);
>  graphics.endFill();
>  }
> }
> }
>
>
> *QuantityComponent*
>
>
> <?xml version="1.0" encoding="utf-8"?>
> <s:Group xmlns:fx="http://ns.adobe.com/mxml/2009";
> xmlns:s="library://ns.adobe.com/flex/spark" preinitialize="init(event)" >
>  <fx:Script>
> <![CDATA[
> import com.isa.mobile.data.Globals;
>  import com.isa.mobile.events.QuantityComponentEvent;
>  import mx.core.FlexGlobals;
>  import mx.events.FlexEvent;
>  [Bindable]
>  private var minQuantity:Number = 0;
>  [Bindable]
>  private var maxQuantity:Number;
>  [Bindable]
>  private var noMaxQuantity:Boolean = false;
>  [Bindable]
>  private var heading:String;
>  [Bindable]
>  private var qty:Number = 0;
>  [Bindable]
>  private var componentHeight:Number;
>  [Bindable]
>  private var defButtonHeight:Number;
>  [Bindable]
>  private var defLabelHeight:Number;
>  [Bindable]
>  private var defPadding:Number;
>  public function
> initializeQuantityComponent(heading:String,minQty:Number=0,maxQty:Number=0):QuantityComponent{
>  this.minQuantity = minQty;
> this.maxQuantity = maxQty;
> this.heading = heading;
>  return this;
> }
>  protected function decrementQty(event:MouseEvent):void
>  {
> if((qty-1) >= minQuantity){
> --qty;
>  FlexGlobals.topLevelApplication.dispatcher.dispatchEvent(new
> QuantityComponentEvent(QuantityComponentEvent.QUANTITY_CHANGED,this,this.qty));
> }
>  }
>  protected function incrementQty(event:MouseEvent):void
>  {
> if(!noMaxQuantity){
> if((qty+1) <= maxQuantity){
>  ++qty;
> FlexGlobals.topLevelApplication.dispatcher.dispatchEvent(new
> QuantityComponentEvent(QuantityComponentEvent.QUANTITY_CHANGED,this,this.qty));
>  }
> }else{
> ++qty;
>  FlexGlobals.topLevelApplication.dispatcher.dispatchEvent(new
> QuantityComponentEvent(QuantityComponentEvent.QUANTITY_CHANGED,this,this.qty));
> }
>  }
>  public function setMinQuantity(min:Number):void{
>  this.minQuantity = min;
> }
>  public function setMaxQuantity(max:Number):void{
>  this.maxQuantity = max;
> }
>  public function setNoMaxQuantity(noMaxQty:Boolean):void{
>  this.noMaxQuantity = noMaxQty;
> }
>  public function getComponentHeight():Number{
>  return this.componentHeight;
> }
>  protected function init(event:FlexEvent):void
>  {
> this.defButtonHeight = Globals.getComponentHeight(Globals.BUTTON_HEIGHT);
> this.defLabelHeight = Globals.getComponentHeight(Globals.LABEL_HEIGHT);
>  this.componentHeight =  defLabelHeight + defButtonHeight;
> this.defPadding = Globals.getComponentHeight(Globals.PADDING_SIZE);
>  }
>  public function getQuantity():Number{
>  return this.qty;
> }
>  public function setQuantity(qty:Number):void{
>  this.qty = qty;
> }
>  ]]>
>  </fx:Script>
>  <s:VGroup width="95%"  verticalCenter="0" horizontalCenter="0"
> verticalAlign="middle" horizontalAlign="center">
>  <s:Label height="{defLabelHeight}" textAlign="center"
> verticalAlign="middle" width="100%"  text="{this.heading}"/>
>  <s:HGroup width="100%" >
> <s:Button height="{defButtonHeight}"
> skinClass="com.isa.mobile.skins.ViewDefaultButtonSkin" width="33%"
>  label="-" click="decrementQty(event)" />
>  <s:Label height="{defButtonHeight}" textAlign="center"
> verticalAlign="middle" width="33%" text="{this.qty}"/>
>  <s:Button height="{defButtonHeight}"
> skinClass="com.isa.mobile.skins.ViewDefaultButtonSkin" width="33%"
> label="+" click="incrementQty(event)"/>
>  </s:HGroup>
> </s:VGroup>
> </s:Group>
>
>
> AS YOU CAN SEE IN THE ATTACHED SCREEN SHOTS
> IF I SET THE QUANTITY TO 1 IN THE FIRST MEAL LAST MEAL ALSO UPDATE WITH
> THE SAME VALEUE
>
> also is there a way to disable itemrendere recycling
>
> thanks
> Sumudu
>
>
> On Mon, Jun 10, 2013 at 10:36 AM, Alex Harui <[email protected]> wrote:
>
>> Your renderer should only display stuff based on its data property (or
>> associated data properties).  A button should update a property on each
>> data item which will then be reflected by the renderer when it is used to
>> display an item that was off-screen.
>>
>> -Alex
>>
>> On 6/9/13 9:38 PM, "Sumudu Chinthaka" <[email protected]> wrote:
>>
>> >hi
>> >
>> >i have a list with a custom ItemRenderer with a button on it
>> >when the button click inside a renderer i want to update all other
>> >renderers with some specific value
>> >
>> >so what i did was add a event listener and the handler inside the
>> >itemrendere to response to button click event
>> >
>> >this works fine for the items that are displayed on the screen
>> >i think due to item renderer recycling what ever items that are not
>> >displayed in the screen does not receive this event
>> >as i scroll down the list i could see those items not being update and
>> >only
>> >the top items of the list that were displayed on the screen updated
>> >
>> >how can i force to update all items upon my event
>> >
>> >thanks
>> >Sumudu
>>
>>
>

Reply via email to