Flex exposes a "selectionColor" CSS property for styling the background color of a selected list/datagrid. However, I cannot figure out how to style the foreground or text color of selected list. It appears you can only change the foreground color for all rows.
So, for example, that I wanted a very dark selection background color and a very light deselected background color. You would similarly want a light text color for selection and a dark text color for deselected.
I know I could do this with a custom item renderer, but that seems rather silly. The point is to style all lists/datagrids in my app. I don't want to have to set a custom item renderer or extend Datagrid for each place I use it. Note that I am using Flex 4 and am willing to use skins though I don't know if that means anything considering DataGrid is not sparkified yet.
Flex 3 used textRollOverColor
and textSelectedColor
but Flex 4 components does not support them anymore.
The following example demonstrates all this + adding support for this colors for spark List:
<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">
<fx:Style>
@namespace s "library://ns.adobe.com/flex/spark";
@namespace mx "library://ns.adobe.com/flex/mx";
global
{
textRollOverColor: yellow;
textSelectedColor: green;
}
</fx:Style>
<fx:Script>
<![CDATA[
import mx.collections.ArrayCollection;
private function getListDataProvider():ArrayCollection
{
return new ArrayCollection([ "Item 1", "Item 2", "Item 3"]);
}
private function getGridDataProvider():ArrayCollection
{
return new ArrayCollection([ { name: "Item 1" }, { name: "Item 2" }, { name: "Item 3" } ]);
}
]]>
</fx:Script>
<s:layout>
<s:VerticalLayout horizontalAlign="center" verticalAlign="middle"/>
</s:layout>
<s:List dataProvider="{getListDataProvider()}"/>
<s:List dataProvider="{getListDataProvider()}" itemRenderer="ColoredItemRenderer"/>
<mx:List dataProvider="{getListDataProvider()}"/>
<mx:DataGrid dataProvider="{getGridDataProvider()}"/>
</s:Application>
ColoredItemRenderer
:
<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">
<fx:Script>
<![CDATA[
override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void
{
super.updateDisplayList(unscaledWidth, unscaledHeight);
var color:uint;
if (selected)
color = getStyle("textSelectedColor");
else if (hovered)
color = getStyle("textRollOverColor");
else
color = getStyle("color");
sparkLabel.setStyle("color", color);
}
]]>
</fx:Script>
<s:Label id="sparkLabel" text="{data}"/>
</s:ItemRenderer>
Here is an example on how to do it in Flex 4 using states and itemRenders
<s:List itemRenderer="com.renderer.GlossaryRenderer" change="handleGridClick(event)" width="293" height="206" styleName="glossaryList" dataProvider="{_glossary}">
<s:layout>
<s:VerticalLayout horizontalAlign="justify" paddingLeft="5" requestedRowCount="9" />
</s:layout>
</s:List>
You could set up your item renderer like this
<?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="false">
<s:states>
<s:State name="normal" />
<s:State name="hovered" />
<s:State name="selected" />
</s:states>
<s:Label id="sparkLabel" backgroundColor.selected="#ff0000" color.selected="#FFFFFF" color.hovered="#FFFFFF" text="{data.word}" left="2" right="2" top="4" bottom="4" />
</s:ItemRenderer>
For Spark DataGrid you need to create a new item renderer based on GridItemRenderer. Then assign that to the DataGrid itemRenderer property.
MyGridItemRender.mxml:
<s:GridItemRenderer xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
width="100%"
height="100%">
<fx:Script>
<![CDATA[
override public function prepare(hasBeenRecycled:Boolean):void {
super.prepare(hasBeenRecycled);
var styleClient:IStyleClient = owner as IStyleClient;
var color:uint;
if (selected && styleClient.getStyle("textSelectionColor")!==undefined) {
color = styleClient.getStyle("textSelectionColor");
}
else if (selected && styleClient.getStyle("textSelectedColor")!==undefined) {
color = styleClient.getStyle("textSelectedColor");
}
else if (hovered && styleClient.getStyle("textRollOverColor")!==undefined) {
color = styleClient.getStyle("textRollOverColor");
}
else {
color = styleClient.getStyle("color");
}
labelDisplay.setStyle("color", color);
}
]]>
</fx:Script>
<s:Label id="labelDisplay"
paddingLeft="3" paddingRight="3"
paddingTop="5" paddingBottom="5"
verticalCenter="2"
left="2"/>
</s:GridItemRenderer>
Code:
<s:DataGrid id="dataGrid" itemRenderer="MyGridItemRenderer"/>
You can also use this DataGrid, which has it on by default.