http://www.switchonthecode.com/tutorials/flex-tutorial-image-itemrenderer
Just the other day a commenter on our Flex tutorial about TileList Selection Indicators had a question about how to change something about the selected item. In this case it happened to be about how to change the transparency of images that are in the list. Now instead of actually handling this inside the list itself we are going to write an ItemRenderer for this, you can check out our other tutorial on ItemRenderers for more specific information on the subject. Our ItemRenderer will check to see if the data being rendered is also the selected item of the list.
Below we have a quick demonstration of this technique. You can see that we have a simple TileList with 10 images in it and initially they are all semi-transparent. Then if you select a single image it will become completely opaque revealing the full detail of my horribly compressed JPEGs. You may also notice that I have gotten rid of the selection indicator just like how we learned to in the list selection tutorial. At the same time I have set the background color to a light teal color to show that the images are actually semi-transparent. Ok play around and you can check out the source here.
Custom TileList
First I built a very very simple custom TileList class to take care of the list selection indicator. To do this all you need to do is override the main function that draws this portion of the list. This function is, of course, drawSelectionIndicator
. Once the function is over written I simply returned out of it without drawing any indicator at all. This results in the following class, which I named TileListEx
.
{
import flash.display. Sprite;
import mx.controls.TileList;
import mx.controls.listClasses.IListItemRenderer;
public class TileListEx extends TileList
{
override protected function drawSelectionIndicator (indicator : Sprite,
x : Number, y : Number, width : Number, height : Number, color : uint,
itemRenderer :IListItemRenderer ) : void
{
return;
}
}
}
Main Application
Once the custom TileList class was built it was easy to get things going. The main application only had one tag in it, the TileListEx
. Inside the list we set the dataProvider
by hand and added an array to it. This array holds 10 objects, each with a path property pointed to an image on the server. Here is also where we set a couple minor properties on the list including the color and useRollOver
- a style to tell the list to ignore rollover highlighting. This gives us the following application start.
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" xmlns:local="*"
layout="vertical" verticalAlign="middle" width="475" height="400">
<local:TileListEx id="imageList" width="100%" height="100%"
useRollOver="false" verticalAlign="middle" backgroundColor="#46D1E1">
<local:dataProvider>
<mx:Array>
<mx:Object path="ImageTileList/one.jpg" />
<mx:Object path="ImageTileList/two.jpg" />
<mx:Object path="ImageTileList/three.jpg" />
<mx:Object path="ImageTileList/four.jpg" />
<mx:Object path="ImageTileList/five.jpg" />
<mx:Object path="ImageTileList/six.jpg" />
<mx:Object path="ImageTileList/seven.jpg" />
<mx:Object path="ImageTileList/eight.jpg" />
<mx:Object path="ImageTileList/nine.jpg" />
<mx:Object path="ImageTileList/ten.jpg" />
</mx:Array>
</local:dataProvider>
</local:TileListEx>
</mx:Application>
Now at this point we could run the application but we wouldn't see anything that wonderful. In order to see the cool stuff we need to create our new and improved ItemRenderer - combination hooka and coffee maker, also makes chili and fries.
Image ItemRenderer
Ok so we can now build our new item renderer that will take care of image transparency. Well the first step is simply to build the ItemRenderer. I created a new Flex component named ImageRenderer
based off a Box and added an image. The image's source
property is bound to the path
property of the data
property. Giving us something like below for our first cut.
<mx:Box xmlns:mx="http://www.adobe.com/2006/mxml">
<mx:Image id="img" source="{data.path}" width="200" height="150"/>
</mx:Box>
With this we can now update the list in the application to use the item renderer by setting the itemRenderer
property to ImageRenderer
. The new TileListEx
tag now looks like the following.
itemRenderer="ImageRenderer" verticalAlign="middle" backgroundColor="#46D1E1">
The final thing we need to do is add some actionscript to our ItemRenderer class. This makes the ItemRenderer look like the following - I will define the script after.
<mx:Box xmlns:mx="http://www.adobe.com/2006/mxml" creationComplete="{initRenderer()}">
<mx:Script>
<![CDATA[
import mx.events.FlexEvent;
import mx.controls.TileList;
import mx.events.ListEvent;
import mx.events.IndexChangedEvent;
private var outerList:TileList;
private function initRenderer():void
{
this.outerList = (this.parentDocument as ImageTileList).imageList;
this.outerList.addEventListener(ListEvent.CHANGE, updateSelected);
this.addEventListener(FlexEvent.DATA_CHANGE, checkSelected);
}
private function checkSelected(event:FlexEvent):void
{
if(this.outerList.selectedItem == this.data)
this.img.alpha = 1;
else
this.img.alpha = .3;
}
private function updateSelected(event:ListEvent):void
{
if(event.itemRenderer == this)
this.img.alpha = 1;
else
this.img.alpha = .3;
}
]]>
</mx:Script>
<mx:Image id="img" alpha=".3" source="{data.path}" width="200" height="150"/>
</mx:Box>
Well what do we have up there? First you will notice that there is a function tied to the creation complete event. This is so we can initialize some event listeners. If we look inside the initRenderer
function we see that we first set a private variable to the tile list which we get to from the outerDocument
property. Next we add two event listeners, one to listen for the change event on the tile list and one for the event that is fired when the data changes in this item renderer.
Finally we get to look at the two ways we check to see if we are selected. The checkSelected
function is fired when the item renderer's data changes. At this point we check the outer list to see if the selected item is equal to the data this item renderer is holding. If so we set the image alpha to 1 otherwise set it .3. The second way we check the item selected is in the event handler for the change event on the list. This will check to see if the itemRenderer
property of the event is equal to this item renderer and if so it does the same stuff as the other. We also set the default alpha on the image to .3.
Well I hope this helps at least one person, the person I wrote it for :). Also feel free to check out the source and download it from here. And if anyone has any questions, concerns, or just plain complaints feel free to let us know - unless it's the last one.