Creating data tips on a Spark List control in Flex 4

The following example shows how you can create a data tip on individual items in a Spark List control in Flex 4 by creating a custom item renderer and setting the toolTip property.

Full code after the jump.

The following example(s) require Flash Player 10 and the Adobe Flex 4 SDK. To download the Adobe Flash Builder 4 trial, see www.adobe.com/products/flex/. To download the latest nightly build of the Flex 4 SDK, see opensource.adobe.com/wiki/display/flexsdk/Download+Flex+4.

For more information on getting started with Flex 4 and Flash Builder 4, see the official Adobe Flex Team blog.

<?xml version="1.0" encoding="utf-8"?>
<!-- http://blog.flexexamples.com/2009/08/15/creating-data-tips-on-a-spark-list-control-in-flex-4/ -->
<s:Application name="Spark_List_itemRenderer_toolTip_test"
        xmlns:fx="http://ns.adobe.com/mxml/2009"
        xmlns:s="library://ns.adobe.com/flex/spark"
        xmlns:mx="library://ns.adobe.com/flex/halo">
 
    <s:List id="list"
            labelField="label"
            itemRenderer="skins.CustomItemRendererWithDataTip"
            width="100" height="112"
            horizontalCenter="0" verticalCenter="0">
        <s:dataProvider>
            <s:ArrayList>
                <fx:Object label="One" index="0" />
                <fx:Object label="Two" index="1" />
                <fx:Object label="Three" index="2" />
                <fx:Object label="Four" index="3" />
                <fx:Object label="Five" index="4" />
                <fx:Object label="Six" index="5" />
                <fx:Object label="Seven" index="6" />
                <fx:Object label="Eight" index="7" />
                <fx:Object label="Nine" index="8" />
                <fx:Object label="Ten" index="9" />
            </s:ArrayList>
        </s:dataProvider>
    </s:List>
 
</s:Application>

And the custom item renderer, skins/CustomItemRendererWithDataTip.mxml, is as follows:

<?xml version="1.0" encoding="utf-8"?>
<!-- http://blog.flexexamples.com/2009/08/15/creating-data-tips-on-a-spark-list-control-in-flex-4/ -->
<s:ItemRenderer name="CustomItemRendererWithDataTip"
        xmlns:fx="http://ns.adobe.com/mxml/2009"
        xmlns:s="library://ns.adobe.com/flex/spark"
        focusEnabled="false"
        toolTip="{data.index + ') ' + data.label}">
    <!-- states -->
    <s:states>
        <s:State name="normal" />
        <s:State name="hovered" />
        <s:State name="selected" />
        <s:State name="normalAndShowsCaret"/>
        <s:State name="hoveredAndShowsCaret"/>
        <s:State name="selectedAndShowsCaret"/>
    </s:states>
 
    <s:Rect left="0" right="0" top="0" bottom="0">
        <s:stroke.normalAndShowsCaret>
            <s:SolidColorStroke color="{selectionColor}" weight="1"/>
        </s:stroke.normalAndShowsCaret>
        <s:stroke.hoveredAndShowsCaret>
            <s:SolidColorStroke color="{selectionColor}" weight="1"/>
        </s:stroke.hoveredAndShowsCaret>
        <s:stroke.selectedAndShowsCaret>
            <s:SolidColorStroke color="{selectionColor}" weight="1"/>
        </s:stroke.selectedAndShowsCaret>
        <s:fill>
            <s:SolidColor color.normal="{contentBackgroundColor}"
                    color.normalAndShowsCaret="{contentBackgroundColor}"
                    color.hovered="{rollOverColor}"  
                    color.hoveredAndShowsCaret="{rollOverColor}"
                    color.selected="{selectionColor}"
                    color.selectedAndShowsCaret="{selectionColor}" />
        </s:fill>
    </s:Rect>
    <s:SimpleText id="labelDisplay"
            left="3" right="3" top="6" bottom="4"
            verticalCenter="0" />
 
</s:ItemRenderer>

[GoogleAdsWide]

View source is enabled in the following example.

Due to popular demand, here is the “same” example in a more ActionScript friendly format:

<?xml version="1.0" encoding="utf-8"?>
<!-- http://blog.flexexamples.com/2009/08/15/creating-data-tips-on-a-spark-list-control-in-flex-4/ -->
<s:Application name="Spark_List_itemRenderer_toolTip_test"
        xmlns:fx="http://ns.adobe.com/mxml/2009"
        xmlns:s="library://ns.adobe.com/flex/spark"
        xmlns:mx="library://ns.adobe.com/flex/halo"
        initialize="init();">
 
    <fx:Script>
        <![CDATA[
            import mx.collections.ArrayList;
            import skins.CustomItemRendererWithDataTip;
            import spark.components.List;
 
            protected var list:List;
 
            protected function init():void {
                var dp:ArrayList = new ArrayList();
                dp.addItem({label:"One", index:0});
                dp.addItem({label:"Two", index:1});
                dp.addItem({label:"Three", index:2});
                dp.addItem({label:"Four", index:3});
                dp.addItem({label:"Five", index:4});
                dp.addItem({label:"Six", index:5});
                dp.addItem({label:"Seven", index:6});
                dp.addItem({label:"Eight", index:7});
                dp.addItem({label:"Nine", index:8});
                dp.addItem({label:"Ten", index:9});
 
                list = new List();
                list.dataProvider = dp;
                list.labelField = "label";
                list.itemRenderer = new ClassFactory(CustomItemRendererWithDataTip);
                list.width = 100;
                list.height = 112;
                list.horizontalCenter = 0;
                list.verticalCenter = 0;
                addElement(list);
            }
        ]]>
    </fx:Script>
 
</s:Application>

This entry is based on a beta version of the Flex 4 SDK and therefore is very likely to change as development of the Flex SDK continues. The API can (and will) change causing examples to possibly not compile in newer versions of the Flex 4 SDK.

10 thoughts on “Creating data tips on a Spark List control in Flex 4

  1. Hi.
    do you know how to get BitmapData from spark components? is it possible?
    i’ve lost 2-3 days to find the answer, but all of gumbonents and FXG is invisible

    1. @cemaprjl,

      Good timing, I was just looking at this yesterday and haven’t gotten around to doing an example yet. I found you could do this three ways: using flash.display.BitmapData.draw(), using spark.utils.BitmapUtil.getSnapshot(), and using mx.graphics.ImageSnapshot.captureBitmapData():

      <?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">
          <s:layout>
              <s:HorizontalLayout verticalAlign="middle" paddingLeft="20" />
          </s:layout>
       
          <fx:Script>
              <![CDATA[
                  import mx.graphics.ImageSnapshot;
                  import spark.utils.BitmapUtil;
       
                  protected function button1_clickHandler(evt:MouseEvent):void {
                      // Using flash.display.BitmapData.draw()
                      var bmd:BitmapData = new BitmapData(gr1.width, gr1.height, true);
                      bmd.draw(gr1);
                      img1.source = bmd;
       
                      // Using spark.utils.BitmapUtil.getSnapshot()
                      img2.source = BitmapUtil.getSnapshot(gr1);
       
                      // Using mx.graphics.ImageSnapshot.captureBitmapData()
                      img3.source = ImageSnapshot.captureBitmapData(gr1);
                  }
              ]]>
          </fx:Script>
       
          <s:Panel id="pan1" title="Source {gr1.width}x{gr1.height}">
              <s:VGroup id="gr1">
                  <s:Rect width="100%" height="80">
                      <s:fill>
                          <s:SolidColor color="red" />
                      </s:fill>
                  </s:Rect>
                  <s:Button label="Spark Button" />
                  <s:List id="list" height="100" width="150">
                      <s:dataProvider>
                          <s:ArrayList source="[The,Quick,Brown,Fox,Jumps,Over,The,Lazy,Dog]" />
                      </s:dataProvider>
                  </s:List>
              </s:VGroup>
          </s:Panel>
       
          <s:VGroup>
              <s:Button label="take bitmap -&gt;" click="button1_clickHandler(event)" />
          </s:VGroup>
       
          <s:Panel id="pan2" title="BitmapData {img1.width}x{img1.height}">
              <s:BitmapImage id="img1" />
          </s:Panel>
       
          <s:Panel id="pan3" title="BitmapUtil {img2.width}x{img2.height}">
              <s:BitmapImage id="img2" />
          </s:Panel>
       
          <s:Panel id="pan4" title="ImgSnapshot {img3.width}x{img3.height}">
              <s:BitmapImage id="img3" />
          </s:Panel>
       
      </s:Application>

      Peter

  2. Thanks for the post..any idea how to change the tooltip color in spark? I’ve tried to use the following in conjunction with what you have here, but it doesn’t seem to get picked up…

        <fx:Style>
            ToolTip {
                backgroundColor: black;
                backgroundAlpha: 1.0;
                cornerRadius: 0;
                color: white;
            }
        </fx:Style>
    1. @Brad Johnson,

      You typically need a namespace prefix in the <fx:Style/> blocks now:

      <?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/halo">
       
          <fx:Style>
              @namespace s "library://ns.adobe.com/flex/spark";
              @namespace mx "library://ns.adobe.com/flex/halo";
       
              mx|ToolTip {
                  backgroundColor: black;
                  backgroundAlpha: 1.0;
                  cornerRadius: 0;
                  color: white;
              }
          </fx:Style>
       
          <s:Button id="btn"
                  label="Spark Button"
                  creationComplete="btn.toolTip = mx_internal::VERSION;"
                  horizontalCenter="0" verticalCenter="0" />
       
      </s:Application>

      There are ways to get around the prefix, but I like to keep the CSS namespaces in there to make things a bit more clear. In other words, you COULD do something like this, but I personally wouldn’t recommend it (but it is valid):

      <fx:Style>
          @namespace "library://ns.adobe.com/flex/halo";
       
          ToolTip {
              backgroundColor: black;
              backgroundAlpha: 1.0;
              cornerRadius: 0;
              color: white;
          }
      </fx:Style>

      Peter

  3. Hi
    i have been working on flex 4 for sometime i really like the skinnning part of flex4 but i guess the usability wise flex 4 isnt similar as flex 3
    for a spark list control there isnt any item click event, and the selection changed event acts funny by firing 2 times when clicked on any item on list control, not only that it also fires when the data provider is changed.
    do you know any way we can restrict this, this is creating a night mare to me

    i ll appreciate your help

    Thanks,
    Lisa

    1. @Lisa,

      Correct, I don’t believe there is an itemClick event, but there should be a change and changing event which should let you do the same thing.

      As for the selection change events being dispatched 2 times when clicked, can you please file a bug at http://bugs.adobe.com/flex/ and somebody from the Flex SDK team can investigate.

      Thanks,
      Peter

      1. Yeah, but you need an itemClick event when you want to processing for when you click on the same item over again, which doesn’t fire change or changing… You have to do a custom implementation utilizing the click event and checking the current target and the target, but this seems dodgey.

        I’m not sure why they decided to take out itemClick event from spark list… i hope they put it back

  4. Thanks for the quick response.

    I checked out the jira link, but the work around essentially describes what I already did, but doesn’t address the fact that if I try clicking on the very top border of the spark list component (basically need to find that sliver of pixels that makes the hover highlighting go away from the top most item in the list, but is still within the list), then I need to make an explicit check for this mouse event:

    if (!(event.target is ScrollerSkin)) {}

    The reason is because at this point, the highlighting is gone from the first item in the spark list, but when the user clicks in this area, then the mouse event still gets fired. So essentially it looks as if the user isn’t clicking on an item, but the mouse event still fires, so I need to make sure nothing happens.

    It’s a fringe case that probably wont be noticed too often, but still, I find it a nuisance that I have to figure out this kind of quirk when the MX itemClick event handled the case of ONLY clicking on the item.

    1. @Daniel,

      If the workarounds aren’t working for you (or even if they are), please please please feel free to comment in the JIRA bugs and add your feedback. We’re always considering things like itemClick events and other enhancements. They may not make it into the SDK right away, but without customer feedback we don’t know what is important and not.

      Thanks,
      Peter

Comments are closed.