What I said in my last comment referred to the QuantityComponent and not
the item-renderer itself.
Anyway, it is still better to dispatch bubbling events and handle them
where needed than using topLevelApplication for that purpose...


On Mon, Jun 10, 2013 at 9:51 AM, Evyatar Ben Halevi-Arbib <
[email protected]> wrote:

> 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