where should setStyle logic go in Itemrenderers's overided methods - apache-flex

I have following itemrenderer
<?xml version="1.0" encoding="utf-8"?>
<s:MXAdvancedDataGridItemRenderer xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark" xmlns:mx="library://ns.adobe.com/flex/mx" focusEnabled="true">
<s:Label id="lblData" top="0" left="0" right="0" bottom="0" text="{listData.label}" />
<fx:Script>
<![CDATA[
import mx.events.FlexEvent;
override public function set data(value:Object):void
{
if(value != null)
{
super.data = value;
if(value.age >30 )
lblData.setStyle("backgroundColor","red");
else
lblData.setStyle("backgroundColor","green");
}
//super.invalidateDisplayList();
}
override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void
{
super.updateDisplayList(unscaledWidth,unscaledHeight);
if(super.data)
{
}
}
]]>
</fx:Script>
</s:MXAdvancedDataGridItemRenderer>
My question is Should above logic go in updtaeDisplayList or remain in set data() itself.
The output is smae from both. Whats the performance impact difference if we consider it from lifecycle perspective.(The heavy computations should be pushed towards the end of the frame rendering)

In your way I'd rather use invalidateProperties() and commintProperties(). But what about using data binding?
<?xml version="1.0" encoding="utf-8"?>
<s:MXAdvancedDataGridItemRenderer xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark" xmlns:mx="library://ns.adobe.com/flex/mx" focusEnabled="true">
<s:Label top="0" left="0" right="0" bottom="0" text="{listData.label}" backgroundColor="{data.age > 30 ? `red` : `green`}" />
</s:MXAdvancedDataGridItemRenderer>

Related

How to remove the caret indicator on Spark DataGrid

I couldn't find a simple way to get remove or hide the caretIndicator in the Spark DataGrid so I'm posting the solution here if there's not a better way.
This seems to work. To hide the caretIndiator we have to create a new data grid skin based on spark.skins.spark.DataGridSkin. Then in that skin set the alpha of the stroke or alpha of the rect to 0.
Method 1:
MXML:
<s:DataGrid skinClass="view.skins.AbstractDataGridSkin"/>
AbstractDataGridSkin:
<?xml version="1.0" encoding="utf-8"?>
<spark:DataGridSkin
xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
xmlns:fb="http://ns.adobe.com/flashbuilder/2009"
xmlns:spark="spark.skins.spark.*"
xmlns:skins="view.skins.*"
>
<fx:Component id="caretIndicator">
<s:Rect implements="spark.components.gridClasses.IGridVisualElement" alpha="0">
<fx:Script>
<![CDATA[
import spark.components.DataGrid;
import spark.components.Grid;
/**
* #private
*/
public function prepareGridVisualElement(grid:Grid, rowIndex:int, columnIndex:int):void
{
const dataGrid:DataGrid = grid.dataGrid;
if (!dataGrid)
return;
const color:uint = dataGrid.getStyle("caretColor");
caretIndicatorFill.color = color;
}
]]>
</fx:Script>
<s:stroke>
<!--- #private -->
<s:SolidColorStroke id="caretIndicatorFill" color="0x0167FF" weight="0" alpha="0"/>
</s:stroke>
</s:Rect>
</fx:Component>
</spark:DataGridSkin>
Method 2:
There's another method that involves duplicating the default datagrid skin and removing the caretIndicator property. That ways probably better : P.
Method 3:
This also works:
<spark:DataGridSkin
xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
xmlns:fb="http://ns.adobe.com/flashbuilder/2009"
xmlns:spark="spark.skins.spark.*"
xmlns:skins="view.skins.*"
initialize="caretIndicator = null" />

Change background-color Cell in Datagrid (Flex 4.6)

I'm trying to alternate between two background colors for each cell in a datagrid. It changes its state upon double clicking in a particular cell.
What I want is that the user be able to select individuals cell in a Datagrid so #FFFFFF color is for unselected cells and #CDCDCD for selected ones.
I have the following code for an ItenRenderer:
<?xml version="1.0" encoding="utf-8"?>
<s:GridItemRenderer xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
clipAndEnableScrolling="true">
<fx:Script>
<![CDATA[
override public function prepare(hasBeenRecycled:Boolean):void {
//lblData.text = data[column.dataField]
}
]]>
</fx:Script>
<s:states>
<s:State name="normal"/>
<s:State name="selected"/>
</s:states>
<s:Label id="lblData" top="9" left="7" text="10" width="100%" height="100%" textAlign="center"/>
<s:Rect width="100%" height="100%">
<s:fill>
<s:SolidColor color.selected="#CDCDCD" color.normal="#FFFFFF"/>
</s:fill>
</s:Rect>
</s:GridItemRenderer>
The question is that label is never shown due to the rect component hide it. how can i accomplish this?
Thanks in advance.
Try this:
//Application
<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600">
<fx:Script>
<![CDATA[
import mx.collections.ArrayCollection;
[Bindable]private var initDG:ArrayCollection = new ArrayCollection([
{Artist:'01', Album:'Album 01', Year:'2008'},
{Artist:'02', Album:'Album 02', Year:'2009'},
{Artist:'03', Album:'Album 03', Year:'2007'},
{Artist:'04', Album:'Album 04', Year:'2003'},
]);
]]>
</fx:Script>
<s:VGroup>
<s:DataGrid id="myGrid" width="360" dataProvider="{initDG}">
<s:columns>
<s:ArrayList>
<s:GridColumn dataField="Artist" headerText="Artist" itemRenderer="com.dgcoloredcells.CellRenderer"/>
<s:GridColumn dataField="Album" headerText="Album" itemRenderer="com.dgcoloredcells.CellRenderer"/>
<s:GridColumn dataField="Year" headerText="Year" itemRenderer="com.dgcoloredcells.CellRenderer"/>
</s:ArrayList>
</s:columns>
</s:DataGrid>
</s:VGroup>
</s:Application>
//Renderer
<?xml version="1.0" encoding="utf-8"?>
<s:GridItemRenderer xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
implements="mx.controls.listClasses.IDropInListItemRenderer">
<fx:Script>
<![CDATA[
import mx.controls.dataGridClasses.DataGridListData;
import mx.controls.listClasses.BaseListData;
private var _listData:BaseListData;
[Bindable]private var isSelected:Boolean = false;
override public function set data( value:Object ) : void
{
super.data = value;
lblData.text = data[column.dataField];
}
[Bindable]public function get listData() : BaseListData
{
return _listData;
}
public function set listData( value:BaseListData ) : void
{
_listData = value;
}
private function onClick(evt:Event):void
{
isSelected = !isSelected;
}
]]>
</fx:Script>
<s:Rect width="100%" height="100%">
<s:fill>
<s:SolidColor color="{isSelected ? 0xCDCDCD : 0xFFFFFF}"/>
</s:fill>
</s:Rect>
<s:Label id="lblData" top="9" left="7" width="100%" height="100%" textAlign="center" doubleClickEnabled="true" doubleClick="onClick(event)"/>
</s:GridItemRenderer>
//EDIT
Here you can see my screenshot for data[column.dataField] problem:
Here is the coresponding value object
So data[column.dataField] = data["Artist"] = "01"

Close a Callout inside a View in Flex

I have this ViewNavigator inside a callout and the callout displays a view inside it using firstView="views.ListMenusHomeView" . Now how can I close the callout from ListMenusHomeView? Hope someone can help.
Here is my code for the callout:
<?xml version="1.0" encoding="utf-8"?>
<s:Callout xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
contentBackgroundAppearance="none"
height="300" width="300">
<fx:Declarations>
<fx:XML id="menu" source="xmldata/menu2.xml" />
</fx:Declarations>
<fx:Script>
<![CDATA[
import spark.events.PopUpEvent;
protected function back(event:MouseEvent):void {
if(viewNav.length>1)
viewNav.popView();
}
]]>
</fx:Script>
<s:ViewNavigator id="viewNav" width="100%" height="100%" firstView="views.ListMenusHomeView">
<s:navigationContent>
<s:Button label="Back" click="back(event)"/>
</s:navigationContent>
<s:actionContent>
<s:Button label="Cancel" click="close(false)" emphasized="true"/>
</s:actionContent>
</s:ViewNavigator>
</s:Callout>
You see that there is a ViewNavigator which holds the ListMenusHomeView. This is the code for the ListMenusHomeView.
<?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" title="Main Menu" creationComplete="onCreationComplete()">
<fx:Declarations>
<fx:XML id="menu" source="xmldata/menu2.xml" />
</fx:Declarations>
<fx:Script>
<![CDATA[
import com.adobe.serializers.xml.XMLDecoder;
import mx.collections.ArrayCollection;
import spark.events.IndexChangeEvent;
[Bindable]
private var dataArray:ArrayCollection = new ArrayCollection();
private var object:DataArray = new DataArray();
private function onCreationComplete() : void{
var decoder:XMLDecoder = new XMLDecoder();
var resultObj:Object = decoder.decode(menu);
dataArray = object.onCreationComplete(menu, menu.menuitem, resultObj, resultObj.menuitem);
}
protected function list1_changeHandler(event:IndexChangeEvent):void
{
}
]]>
</fx:Script>
<s:List id="tileLayout"
width="100%" height="100%"
verticalScrollPolicy="off" horizontalScrollPolicy="on"
pageScrollingEnabled="true" dataProvider="{dataArray}"
itemRenderer="renderers.iconList2" change="list1_changeHandler(event)">
<s:layout>
<s:TileLayout orientation="columns" requestedRowCount="3"
verticalGap="20" horizontalGap="20"/>
</s:layout>
</s:List>
Now I want to close MyCallout whenever I click an icon inside ListMenusHomeView. The function list1_changeHandler(event:IndexChangeEvent) is responsible for that one.
What should I do?
The Callout class has a close() method, so you basically just need to access the ListMenusHomeViews parentDocument (which would be your "viewNav" ViewNavigator) and its parentDocument, which should be your ListMenusHomeView.
I haven't tested it but you might fiddle around with the parentDocument, parent and owner properties to access the correct object. Try them with a simple trace and you'll be up and running in no time.

load image from filesystem in flex

i have the following:
<s:Image source="{path}/imageName"/>
how can i determine that path to load the image from filesystem lets say from
C:\Users\sstauross\Desktop ??
Edit : If you want to select a specific path, the user will have to confirm the path himself first using the FileSystemList
<?xml version="1.0" encoding="utf-8"?>
<s:WindowedApplication xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx">
<fx:Script>
<![CDATA[
import mx.events.FlexEvent;
private var userPath:String;
protected function button_clickHandler(event:MouseEvent):void
{
userPath = fsList.selectedPath;
}
]]>
</fx:Script>
<s:layout>
<s:VerticalLayout/>
</s:layout>
<mx:FileSystemList id="fsList"/>
<s:Label text="{fsList.selectedPath}"/>
<s:Button label="Confirm folder selection" click="button_clickHandler(event)"/>
</s:WindowedApplication>
Here's one way to do it
<?xml version="1.0" encoding="utf-8"?>
<s:WindowedApplication xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx" creationComplete="creationCompleteHandler(event)">
<fx:Script>
<![CDATA[
import mx.events.FlexEvent;
[Bindable]
private var desktopPath:String;
protected function creationCompleteHandler(event:FlexEvent):void
{
desktopPath = File.desktopDirectory.nativePath.toString();
}
]]>
</fx:Script>
<mx:Image source="{desktopPath}/myFile.jpg"/>
</s:WindowedApplication>
The answer to what i was looking was very simple because i put
<s:Image source="C:\Users\sstauross\Desktop\imageName"/>
instead of
<s:Image source="C:/Users/sstauross/Desktop/imageName"/>
notice the "\" instead of "/"...
Thanks a lot for your answers!

How to set Source of s:BitmapFill dynamically? (Flash Builder, Code Inside)

In Flash Builder (flex 4) I try to use next code to set selected by user (from file system) Image as a repeated background. It worked with mx:Image but I want to use cool repited capabiletis of s:BitmapFill.
BTW: Technic I use also does not work with S:BitmapImage. Also FP does not return any errors. What Shall I do with my code to make it work?
<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
xmlns:net="flash.net.*"
minWidth="955" minHeight="600" >
<fx:Script>
<![CDATA[
import mx.controls.Alert;
import mx.utils.ObjectUtil;
private function btn_click(evt:MouseEvent):void {
var arr:Array = [];
arr.push(new FileFilter("Images", ".gif;*.jpeg;*.jpg;*.png"));
fileReference.browse(arr);
}
private function fileReference_select(evt:Event):void {
fileReference.load();
}
private function fileReference_complete(evt:Event):void {
img.source = fileReference.data;
Alert.show(ObjectUtil.toString(fileReference));
}
]]>
</fx:Script>
<fx:Declarations>
<net:FileReference id="fileReference"
select="fileReference_select(event);"
complete="fileReference_complete(event);" />
</fx:Declarations>
<s:Rect id="backgroundRect" left="0" right="0" top="0" bottom="0">
<s:fill>
<s:BitmapFill id="img" source="#Embed('1.jpg')" fillMode="repeat" />
</s:fill>
</s:Rect>
<mx:Button id="btn"
label="Browse and preview..."
click="btn_click(event);" />
</s:Application>
Check this code:
private function fileReference_complete(evt:Event):void {
var loader:Loader = new Loader();
loader.loadBytes(fileReference.data);
loader.contentLoaderInfo.addEventListener(Event.COMPLETE,loaderCompleteHandler);
}
private function loaderCompleteHandler(evt:Event):void{
img.source = evt.target.content;
}
So you need to use a loader in order to create the bitmap object.

Resources