The optimized way to show text - performance

I am in a process of optimizing item renderers that display a character in a Rect, I notice that the action of dynamically setting the text is slow, now I am thinking of creating premade objects with text hard-coded in them and inside the item-renderer have a switch to select the proper text object instead of using .text = , does anyone have any other idea on how to optimize the renderer , it is a tile layout that displays about 100 renderers on screen.
also - what is the cheapest(performance-wize) text object I can use in a renderer?
Thanks
<!-- DNA Plus -->
<s:Group height="26" width="100%" y="20">
<s:Rect id="backgroundTop" left="0" right="0" top="0" bottom="0"
alpha="{(data as MiniBrick).brick.strand == StrandEnum.PLUS.value ? 1 : 0.7}">
<s:fill>
<s:SolidColor id="bgFillTop" color="{BrickColors.getColor((data as MiniBrick).brick)}"/>
</s:fill>
</s:Rect>
<s:Rect id="selectedBackgroundTop" left="0" right="0" top="2" bottom="1" includeIn="selected">
<s:fill>
<s:SolidColor id="sBgFillTop" color.selected="0xB6E0F2"/>
</s:fill>
</s:Rect>
<!--- #copy spark.components.supportClasses.SkinnableTextBase#textDisplay -->
<s:Label id="textDisplayTop" width="100%" top="4" fontFamily="Consolas" text="{(data as MiniBrick).origin}"
fontSize="20" lineBreak="explicit" verticalAlign="middle" textAlign="center"/>
</s:Group>
<!-- DNA Minus -->
<s:Group height="26" width="100%" y="46">
<s:Rect id="backgroundBottom" left="0" right="0" top="0" bottom="0"
alpha="{(data as MiniBrick).brick.strand == StrandEnum.MINUS.value ? 1 : 0.7}">
<s:fill>
<s:SolidColor id="bgFillBottom" color="{BrickColors.getColor((data as MiniBrick).brick)}"/>
</s:fill>
</s:Rect>
<s:Rect id="selectedBackgroundBottom" left="0" right="0" top="1" bottom="2" includeIn="selected">
<s:fill>
<s:SolidColor id="sBgFillBottom" color.selected="0xB6E0F2"/>
</s:fill>
</s:Rect>
<!--- #copy spark.components.supportClasses.SkinnableTextBase#textDisplay -->
<s:Label id="textDisplayBottom" width="100%" top="4" fontFamily="Consolas" text="{DnaDictionary.getComplementSequenceOneLetter((data as MiniBrick).origin)}"
fontSize="20" lineBreak="explicit" verticalAlign="middle" textAlign="center"/>
</s:Group>
<!-- DNA index [tick list] -->
<s:Group width="15" id="dnaTick" y="72">
<s:Rect horizontalCenter="0" width="2" height="2" radiusX="1">
<s:fill>
<s:SolidColor color="#666666"/>
</s:fill>
</s:Rect>
<s:Label id="dnaTickLabel" horizontalCenter="0" y="5" height="9" color="#888888" fontFamily="Arial" fontSize="9"
textAlign="left" />
</s:Group>
<s:Line id="firstMiniBrickInBrickLine" x="0" y="20" yFrom="72">
<s:stroke>
<s:SolidColorStroke caps="none" color="#FFFFFF" weight="1"/>
</s:stroke>
</s:Line>

To answer your question directly: the most optimized way to display text is to use the UITextField class. But you're going to have a hard time implementing that into your ItemRenderer since it doesn't inherit from UIComponent.
Also that is not where the most performance gain is to be made in your code. The biggest problem is that this renderer has 6 data bindings in it. If you have 100 items on screen, that makes for 600 listeners watching for data changes.
So you should remove all those bindings and set those properties by overriding the ItemRenderer's data setter, like so:
override public function set data(value:Object):void {
super.data = value;
var brick:MiniBrick = value as MiniBrick;
backgroundTop.alpha = brick.brick.strand == StrandEnum.PLUS.value ? 1 : 0.7;
bgFillTop.color = BrickColors.getColor(brick.brick);
...
}
If you want to optimize even further, I would suggest you put the information for the renderers directly on the data so that it doesn't have to be evaluated every time and you can write the following:
override public function set data(value:Object):void {
super.data = value;
var brick:MiniBrick = value as MiniBrick;
backgroundTop.alpha = brick.alpha;
bgFillTop.color = brick.color;
...
}

Related

Filters and Gradient colors not getting applied simultaneously for button skin

I have created a sample desktop app using Flex 4 in flash builder 4 wherein I am using a button inside BorderContainer.
I have applied skin to button which includes Dropdownshadow,glow filter,bevel-filter and gradient colors.
But I am facing a problem with use of filters and gradient fill simultaneously.
When using filters gradient fill doesnt show up and vice-versa.
Please let me know where I am making mistake.
This is the main.mxml code:
<s:BorderContainer backgroundColor="#003C7B" verticalCenter="0" horizontalCenter="0" height="350" width="450">
<s:Button id="btn" label="Select" color="white" verticalCenter="0" skinClass="BlueButtonSkin" horizontalCenter="0"/>
</s:BorderContainer>
The skin class code for filters and gradient fill is as follows:
<s:Rect id="backgroundAndShadow" left="0" right="0" top="0" bottom="0" radiusX="5" radiusY="5"
topLeftRadiusX="5" topLeftRadiusY="5" topRightRadiusX="5" topRightRadiusY="5"
bottomLeftRadiusX="5" bottomLeftRadiusY="5" bottomRightRadiusX="5" bottomRightRadiusY="5">
<s:fill>
<s:LinearGradient rotation="90">
<s:GradientEntry color="#00366E"/>
<s:GradientEntry color="#013A8B" />
</s:LinearGradient>
</s:fill>
<s:filters>
<s:GlowFilter alpha="0.9" color="#ffffff" inner="false" knockout="true" blurX="8" blurY="8" />
<s:BevelFilter angle="270" distance="5" />
</s:filters>
</s:Rect>
<s:RectangularDropShadow id="dropShadow" blurX="8" blurY="8" alpha="0.5" distance="5" tlRadius="5" trRadius="5" blRadius="5" brRadius="5"
angle="45" color="#000000" left="2" top="0" right="0" bottom="0"/>
<s:Rect id="border" left="0" right="0" top="0" bottom="0" width="75" height="15"
topLeftRadiusX="5" topLeftRadiusY="5" topRightRadiusX="5" topRightRadiusY="5"
bottomLeftRadiusX="5" bottomLeftRadiusY="5" bottomRightRadiusX="5" bottomRightRadiusY="5">
<s:stroke>
<s:SolidColorStroke joints="bevel" caps="round" color="#84C2F2" weight="0.3" alpha="0.3"/>
</s:stroke>
</s:Rect>
<s:Label id="labelDisplay"
textAlign="center"
verticalAlign="middle"
maxDisplayedLines="2"
horizontalCenter="0" verticalCenter="0"
left="10" right="10" top="2" bottom="2">
</s:Label>
Any suggestions on this?
I am attaching the required look for button for reference:
In your <s:GlowFilter /> you have set the knockout property to true. So when applying that filter, it literally knocks out the contents of the item that the filter is applied to. Remove that property altogether or you can set it to false, which is the default.
Here's what the GlowFilter documentation says for the knockout property:
Specifies whether the object has a knockout effect. A knockout effect
makes the object's fill transparent and reveals the background color
of the document. The value true specifies a knockout effect; the
default value is false (no knockout effect).
Well,finally I have done it...
Played with the code and found this code works fine with what is required:
<s:Rect id="backgroundAndShadow2" left="0" right="0" top="0" bottom="0"
topLeftRadiusX="5" topLeftRadiusY="5" topRightRadiusX="5" topRightRadiusY="5"
bottomLeftRadiusX="5" bottomLeftRadiusY="5" bottomRightRadiusX="5" bottomRightRadiusY="5">
<s:fill>
<s:SolidColor color="#4B7CB6" alpha="0.5"/>
</s:fill>
<s:filters>
<s:DropShadowFilter blurX="5" blurY="5" quality="3" strength="0.65" distance="4" />
<s:GlowFilter blurX="7" blurY="7" quality="3" color="#004DAF"/>
<s:BevelFilter blurX="1" blurY="1" quality="3" strength="2" highlightColor="#9FC7F5" angle="60" distance="1"/>
<s:BlurFilter blurX="1.5" blurY="1.5"/>
</s:filters>
</s:Rect>
<s:Rect id="backgroundAndShadow" left="1.5" right="1.5" top="1.5" bottom="1.5"
topLeftRadiusX="5" topLeftRadiusY="5" topRightRadiusX="5" topRightRadiusY="5"
bottomLeftRadiusX="5" bottomLeftRadiusY="5" bottomRightRadiusX="5" bottomRightRadiusY="5">
<s:fill>
<s:LinearGradient scaleX="51" rotation="90">
<s:GradientEntry ratio="0" color="#013465"/>
<s:GradientEntry ratio="0.32156863" color="#013A7F"/>
<s:GradientEntry ratio="1" color="#003990"/>
</s:LinearGradient>
</s:fill>
<s:filters>
<s:DropShadowFilter inner="true" angle="-130" blurX="2" blurY="0.8" strength="0.5" color="#00275C" alpha="0.8"/>
</s:filters>
</s:Rect>
<s:Label id="labelDisplay"
textAlign="center"
verticalAlign="middle"
maxDisplayedLines="2"
horizontalCenter="0" verticalCenter="0"
left="10" right="10" top="2" bottom="2">
</s:Label>
Modified the skinclass and got the results!

flex:how to make some sparkgrid columns editable

I want to make two spark grid columns editable on check box click event.I have written following code for that. but i dont have java function to implement this.
so can anyone plz help me..?
<s:DataGrid id="dataGrid" x="3" y="44" width="792" height="243" editable="true" fontSize="15"
requestedRowCount="4" dataProvider="{getSalesReturnCgt.lastResult}">
<s:columns>
<s:ArrayList>
<s:GridColumn dataField="selectFlag" rendererIsEditable="true" headerText="SrNo" width="60" editable="false">
<s:itemRenderer>
<fx:Component>
<s:GridItemRenderer>
<s:layout>
<s:HorizontalLayout horizontalAlign="center" verticalAlign="middle"/>
</s:layout>
</fx:Script>
<s:Label id="srno" text="{cgtsrobj.sr_no}" />
<s:CheckBox id="chkBox" click="chkBox_clickHandler(event)" />
</s:GridItemRenderer>
</fx:Component>
</s:itemRenderer>
</s:GridColumn>
<s:GridColumn dataField="lot_Id" headerText="Item"></s:GridColumn>
<s:GridColumn dataField="lot_Description" headerText="Item Description"></s:GridColumn>
<s:GridColumn dataField="local_Price" headerText="Rate"></s:GridColumn>
<s:GridColumn dataField="discount" headerText="Discount"></s:GridColumn>
<s:GridColumn dataField="available_qty" headerText="Avail Qty"></s:GridColumn>
<s:GridColumn dataField="return_qty" headerText="Return Qty" id="txtReturn">
<s:itemEditor>
<fx:Component>
<s:TextInput restrict="0-9" width="20" visible="true" />
</fx:Component>
</s:itemEditor>
</s:GridColumn>
<s:GridColumn dataField="sales_qty" headerText="Sales Qty" >
<s:itemEditor>
<fx:Component>
<s:TextInput restrict="0-9" width="20" visible="true" />
</fx:Component>
</s:itemEditor>
</s:GridColumn>
<s:GridColumn dataField=" " headerText="Amount"></s:GridColumn>
</s:ArrayList>
</s:columns>
First of all, you dont need java code for this, now to achieve this, write the chkBox_clickHandler function, from there you should dispatch an event which you should handle in GridItemEditor

Can you transition using Fade specifying all elements, without listing individually?

I've got the beginning of an air app, and I'm trying to transition between the states using Fade (a Sequence that should, in theory, fade out, then fade the next state in.) Is there a way to target it to fade out ALL the elements, or will I need to use targets="..." and list every element?
I've tried nesting all the elements in a Group, but that isn't seeming to work.
Shortened version of my current code:
<s:states>
<s:State name="HomeScreen"/>
<s:State name="EnemyBuilder"/>
<s:State name="EncyclopediaBuilder"/>
</s:states>
<fx:Declarations>
<s:Transition toState="*" fromState="*" >
<s:Sequence >
<s:Fade alphaFrom="1" alphaTo="0" duration="250" target="{wrapper}" />
<s:Fade alphaFrom="0" alphaTo="1" duration="250" target="{wrapper}" />
</s:Sequence>
</s:Transition>
</fx:Declarations>
<s:Group id="wrapper" includeIn="HomeScreen, EnemyBuilder, EncyclopediaBuilder" >
<s:BorderContainer id="encounter" includeIn="HomeScreen"
x="49" y="99" width="200" height="44"
styleName="falseButton"
rollOut="alphaOver(event)" rollOver="alphaOver(event)" click="currentState='EncyclopediaBuilder'" >
<s:Label x="48" y="8" color="#000000" fontFamily="Arial" text="Create a new encounter" />
<s:Label x="48" y="24" color="#000000" fontStyle="italic" text="Single encounter" />
<s:Image x="10" y="10" source="assets/001_01.png" />
<s:BorderContainer id="back" includeIn="EncyclopediaBuilder"
right="20" bottom="20" width="200" height="44"
styleName="falseButton"
rollOut="alphaOver(event)" rollOver="alphaOver(event)"
click="currentState='HomeScreen'" >
<s:Label x="48" y="16" color="#000000" fontFamily="Arial" text="Save and Return"/>
<s:Image x="10" y="10" source="assets/001_01.png"/>
</s:BorderContainer>
</s:BorderContainer></s:Group>
Try to use something like the following:
<s:states>
<s:State name="HomeScreen"/>
<s:State name="EnemyBuilder"/>
<s:State name="EncyclopediaBuilder"/>
</s:states>
<s:transitions>
<s:Transition toState="*" fromState="*" >
<s:Sequence target="{wrapper}">
<s:Fade alphaFrom="1" alphaTo="0" duration="250" />
<s:Fade alphaFrom="0" alphaTo="1" duration="250" />
</s:Sequence>
</s:Transition>
</s:transitions>
<s:Group id="wrapper">
<s:BorderContainer id="encounter" includeIn="HomeScreen"
x="49" y="99" width="200" height="44"
styleName="falseButton"
rollOut="alphaOver(event)" rollOver="alphaOver(event)" click="currentState='EncyclopediaBuilder'" >
<s:Label x="48" y="8" color="#000000" fontFamily="Arial" text="Create a new encounter" />
<s:Label x="48" y="24" color="#000000" fontStyle="italic" text="Single encounter" />
<s:Image x="10" y="10" source="assets/001_01.png" />
<s:BorderContainer id="back" includeIn="EncyclopediaBuilder"
right="20" bottom="20" width="200" height="44"
styleName="falseButton"
rollOut="alphaOver(event)" rollOver="alphaOver(event)"
click="currentState='HomeScreen'" >
<s:Label x="48" y="16" color="#000000" fontFamily="Arial" text="Save and Return"/>
<s:Image x="10" y="10" source="assets/001_01.png"/>
</s:BorderContainer>
</s:BorderContainer></s:Group>

Flex Component using global variable

I am using Flash Builder 4 Burrito Preview - builing a Mobile Application. I have a custom component called footer.mxml. That footer has 4 buttons, and one of them has a lable that is bound to cartValue. I am trying to maintain a global variable called cartValue within all views and footer component.
footer.mxml
<s:Group xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
width="100%" height="64" chromeColor="#000000" fontSize="10">
<fx:Declarations>
<!-- Place non-visual elements (e.g., services, value objects) here -->
<mx:CurrencyFormatter id="currencyFormatter"
currencySymbol="$"
useThousandsSeparator="true"
precision="2" />
</fx:Declarations>
<fx:Script>
<![CDATA[
[Bindable]
public var cartValue:int;
]]>
</fx:Script>
<s:HGroup width="100%" contentBackgroundColor="#000000" paddingBottom="0" paddingLeft="0"
paddingRight="0" paddingTop="0">
<s:Button x="0" y="624.5" width="25%" height="64" label="Account" chromeColor="#2259AA"
enabled="true" fontSize="10" fontWeight="bold" icon="#Embed('assets/user.png')"/>
<s:Button x="121" y="624.5" width="25%" height="64" label="Orders" chromeColor="#2259AA"
fontSize="10" icon="#Embed('assets/doc_lines_stright.png')"/>
<s:Button x="241" y="624.5" width="25%" height="64" label="Help" chromeColor="#2259AA"
fontSize="10" icon="#Embed('assets/spechbubble.png')"/>
<s:Button x="360" y="624.5" width="25%" height="64" label="{currencyFormatter.format(cartValue)}" chromeColor="#2259AA"
fontSize="10" icon="#Embed('assets/shop_cart.png')"/>
</s:HGroup>
</s:Group>
RincoTest.mxml
<s:MobileApplication xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
backgroundColor="#000000" firstView="views.RincoTestHome"
>
<fx:Style source="RincoTest.css"/>
<fx:Declarations>
<!-- Place non-visual elements (e.g., services, value objects) here -->
</fx:Declarations>
<fx:Script>
<![CDATA[
[Bindable]
public var cartValue:int;
]]>
</fx:Script>
<s:titleContent>
<s:Image left="1" top="3" width="173" height="75" backgroundAlpha="1.0" smooth="true"
source="assets/iphone_large.png"/>
</s:titleContent>
<s:navigationContent>
<mx:Spacer width="10" height="82"/>
</s:navigationContent>
</s:MobileApplication>
And this is how I am implementing it
<components:footer x="1.65" y="614.95" width="100%" height="64" cartValue="{cartValue}"/>
I have tried to bind Application.application.cartValue and
MobileApplication.application.cartValue. Neither of them work.
If there is a better way to maintain a cartValue across the entire application please let me know. This is my first attempt with Flex.
Thanks,
Ernie
Use a static variable in the component.
Reference it as ComponentName.staticVar. Usually, everything that needs to know about the global already knows about (e.g. imports) the component file.
Cheers
Another solution is using a singleton pattern: a single instance that everything references through a static accessor.
The effect is about the same. The only advantage to a static reference to an instance over static properties is that the instance can be part of an inheritance and can fulfill an interface.
I've also had some intermittent problems with binding to static values, but that might have been a previous version, PEBCAK, etc.
Cheers

Help with creating a custom ItemRenderer for Flex 4

I'm trying to create a custom ItemRenderer for a TileList in Flex 4.
Here's my renderer:
<?xml version="1.0" encoding="utf-8"?>
<s:ItemRenderer xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
autoDrawBackground="true">
<mx:Image x="0" y="0" source="../images/blank-offer.png" width="160" height="144" smoothBitmapContent="true"/>
<s:Label x="5" y="20" text="{data.title}" fontFamily="Verdana" fontSize="16" color="#696565" width="155"/>
<s:Label x="5" y="42" text="{data.description}" fontFamily="Verdana" fontSize="8" color="#696565" width="154"/>
<mx:Text x="3" y="59" text="{data.details}" fontFamily="Verdana" fontSize="8" color="#696565" width="157" height="65"/>
<mx:Text x="3" y="122" text="{data.disclaimer}" fontFamily="Verdana" fontSize="5" color="#696565" width="157" height="21"/>
</s:ItemRenderer>
Here's my tile list:
<mx:TileList x="0" y="0" width="100%" height="100%" id="tileList" creationComplete="tileList_creationCompleteHandler(event)" dataProvider="{getDataResult.lastResult}" labelField="title" itemRenderer="renderers.OfferLibraryListRenderer"></mx:TileList>
When I run the app, I get this error:
Error #1034: Type Coercion failed: cannot convert renderers::OfferLibraryListRenderer#32fce0a1 to mx.controls.listClasses.IListItemRenderer.
I think in Flex4 you should use the <s:List> component instead of the <mx:TileList>. I've tried this way and it works.

Resources