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