views:

2578

answers:

3

My item renderer is an image, and the highlight for the selected item is under the image so you cannot see the highlight, is there a way to make the highlight "over" the image?

Thanks.

A: 

Thought of using a border, by padding the image by 2px ? Another alternative that comes to mind is absolute positioning...

Dan
+3  A: 

This is exactly the point at which I realized how complicated certain simple-seeming things in Flex can really be. :)

There are various ways of handling a problem like this one depending on the effect you're after, but the way I've always done it is first by overriding certain functions of the TileList, then by using custom itemRenderers. (I've never been able to figure out how to have the List's graphics object of draw on top of the rendered content, though -- someone else might be able to shed some light on that.)

For example, I'll usually create a new class that extends TileList, then override the methods responsible for drawing the highlight and selection indicators to get a bit more control over the way those functions draw the indicators (or sometimes I'll just comment out their contents altogether, such that nothing gets drawn):

public class MyCustomTileList extends TileList
{
    public function MyCustomTileList()
    {
     super();
    }

    override protected function drawHighlightIndicator(indicator:Sprite, x:Number, y:Number, width:Number, height:Number, color:uint, itemRenderer:IListItemRenderer):void
    {   
     var g:Graphics = Sprite(indicator).graphics;
            g.clear();
            g.beginFill(getStyle("myRolloverColor"), getStyle("myRolloverAlpha"));
            g.drawRect(1, 1, width - 1, height - 1);
            g.endFill();

            indicator.x = x;
            indicator.y = y;
    }

    override protected function drawSelectionIndicator(indicator:Sprite, x:Number, y:Number, width:Number, height:Number, color:uint, itemRenderer:IListItemRenderer):void
    {
     //
    }
}

But as you say, since the graphics object always seems to draw behind the content of the list item, I'll usually opt to use an item renderer to draw something (e.g., a translucent box) on top of the image associated with my data item:

<?xml version="1.0" encoding="utf-8"?>
<mx:Canvas xmlns:mx="http://www.adobe.com/2006/mxml"&gt;

    <mx:Script>
     <![CDATA[

      private function img_rollOver():void
      {
       highlight.visible = true;
      }

      private function img_rollOut():void
      {
       highlight.visible = false;
      }

     ]]>
    </mx:Script>

    <mx:Image id="img" source="{something}" horizontalCenter="0" verticalCenter="0" buttonMode="true" useHandCursor="true" mouseChildren="true" rollOver="img_rollOver()" rollOut="img_rollOut()" />
    <mx:Box id="highlight" alpha="0.1" color="#FFFFFF" horizontalCenter="0" verticalCenter="0" width="{img.width}" height="{img.height}" buttonMode="true" useHandCursor="true" mouseChildren="true" rollOver="img_rollOver()" rollOut="img_rollOut()" visible="false" />

</mx:Canvas>

I'm sure there are other approaches, but this one works pretty well for me, and I usually find other benefits to subclassing the stock Flex controls as well.

Hope it helps!

Christian Nunciato
Thanks, I have a question though, why does you constructor function not match your class name?
John Isaacks
Because I'm a dork. :) I had copied a bit of code, is all. Fixed. (Thanks for noticing!)
Christian Nunciato
The graphics object is always behind a display object's children. There is no way to change that.Personally, I would build your second approach in ActionScript rather than MXML because you can use a primitive Shape or Sprite object for the highlight. Why use a Box, which includes all sorts of container layout logic that you don't need? Overuse of unneeded containers is one of the biggest performance drains in Flex applications. The item renderer shouldn't be based on Canvas either, unless you specifically need scroll bars.
joshtynjala
Well, if we're quibbling... ;) In my case I use both the Box and the Canvas for reasons specific to my own app (having nothing to do with scrollbars, incidentally); my intent was to demonstrate an answer to the question and a workable solution -- that the List's graphics object can't be used to draw over an item renderer, and that the way to do it would be with a custom itemRenderer. I generally choose MXML for simplicity, but as you suggest there are certainly tradeoffs to doing so. The point seems clear enough nonetheless.
Christian Nunciato
A: 

I think it's easier to turn off selection and highlight effects, then create what you're expecting in the renderer. The data for the renderer will need to have some sort of .selected property in it. The renderer can then bind or respond to changes it its data.selected (or something similar) and update it's appearance however you want.

I only use the default visuals on list when I have no other choice. I'd never want to try to extend List to to it (although, good code Christian).

Sean Clark Hess