Welcome!

Welcome to the official BlackBerry Support Community Forums.

This is your resource to discuss support topics with your peers, and learn from each other.

inside custom component

Adobe AIR Development

Reply
Developer
nathanpc
Posts: 134
Registered: ‎05-19-2012
My Device: Torch 9800, PlayBook 64GB, Dev Alpha
My Carrier: VIVO Brazil
Accepted Solution

Passing Arguments to a Custom CellRender

I'm trying to create a simple two labeled list by creating two label label fields using a class called TwoLabelCell which extends AlternatingCellRenderer and looks like this:

 

package views
{
  import flash.text.TextFormat;
  
  import qnx.fuse.ui.listClasses.AlternatingCellRenderer;
  import qnx.fuse.ui.text.Label;

  public class TwoLabelCell extends AlternatingCellRenderer {
    private var description:Label;
    private var labelFormat:TextFormat;
    private var text:String;

    public function TwoLabelCell(labelText:String) {
      this.text = labelText;
    }
    
    override protected function init():void {
      super.init();
      
      labelFormat = new TextFormat();
      labelFormat.color = 0x777777;
      labelFormat.size = 17;
      
      description = new Label();
      description.x = 17;
      description.y = 33;
      description.format = labelFormat;
      description.text = text;
      
      this.addChild(description);
    }
  }
}

Remember that this one is just a test at the time, so I'm working with only one label (after I figure out this question I'll add the other and use the same logic). The main idea here is that when I call this it will set the text variable which will be used to change the text of the label on the list when it's being created. Now, here the main application file:

 

package {
  import flash.display.Sprite;
  
  import qnx.fuse.ui.events.ListEvent;
  import qnx.fuse.ui.listClasses.List;
  import qnx.fuse.ui.listClasses.ListSelectionMode;
  import qnx.fuse.ui.listClasses.ScrollDirection;
  import qnx.ui.data.DataProvider;
  
  import views.TwoLabelCell;
  
  [SWF(height="600", width="1024", frameRate="30", backgroundColor="#FFFFFF")]
  public class PackTrack extends Sprite {
    private var packList:List;

    public function PackTrack() {
      super();
      
      initializeUI();
    }
    
    private function initializeUI():void {
      packList = new List();
      packList.setPosition(0, 0);
      packList.width = 310;
      packList.height = 400;
      packList.rowHeight = 50;
      packList.selectionMode = ListSelectionMode.SINGLE;
      packList.scrollDirection = ScrollDirection.VERTICAL;
      
      var arrMonth:Array=[];
      arrMonth.push({label: "January"});
      arrMonth.push({label: "February"});
      arrMonth.push({label: "March"});
      arrMonth.push({label: "April"});
      arrMonth.push({label: "May"});
      arrMonth.push({label: "June"});
      arrMonth.push({label: "July"});
      arrMonth.push({label: "August"});
      arrMonth.push({label: "September"});
      arrMonth.push({label: "October"});
      arrMonth.push({label: "November"});
      arrMonth.push({label: "December"});
      
      packList.dataProvider = new DataProvider(arrMonth);
      packList.cellRenderer = new TwoLabelCell("Testing Label");
      
      packList.addEventListener(ListEvent.ITEM_CLICKED, onListClick);
      
      this.addChild(packList);
    }
    
    private function onListClick(event:ListEvent):void {
      trace("Item clicked: " + event.data.label);
      trace("Index clicked: " + event.index);
    }
  }
}

When I try to run that I get this error:

 

Error: skin must be Class or String
	at qnx.fuse.ui.listClasses::List/set cellRenderer()[E:\hudson\workspace\GR2_0_0_AIR_SDK_API\src\qnxui\src\qnx\fuse\ui\listClasses\List.as:1069]
	at PackTrack/initializeUI()[/Users/Nathan/Documents/Adobe Flash Builder 4.6/AIRTest/src/PackTrack.as:46]
	at PackTrack()[/Users/Nathan/Documents/Adobe Flash Builder 4.6/AIRTest/src/PackTrack.as:19]

 

Any idea on how to solve this (preferably not using MXML)?

 

PS: I'm learning Flex (coming from Java)

If I helped you please click the "Like" button to support my work.
My apps: CherryNotes - Bookmarked - Requests
Social Me: about.me - Twitter
Please use plain text.
Developer
UberschallSamsara
Posts: 920
Registered: ‎12-29-2010
My Device: PlayBook, Z10 LE, Dev Alpha C

Re: Passing Arguments to a Custom CellRender

Per the API reference it looks like your code should change from:

 

packList.cellRenderer = new TwoLabelCell("Testing Label");

 

to:

 

packList.cellRenderer = TwoLabelCell;

 

Note your error message, "Error: skin must be Class or String" vs. the comment in the API reference,

"Note: Do not pass in an instance of a skin class. This may cause unexpected behavior."

Please use plain text.
Developer
nathanpc
Posts: 134
Registered: ‎05-19-2012
My Device: Torch 9800, PlayBook 64GB, Dev Alpha
My Carrier: VIVO Brazil

Re: Passing Arguments to a Custom CellRender

But that way I can't customize the text of the Label I'm adding.
If I helped you please click the "Like" button to support my work.
My apps: CherryNotes - Bookmarked - Requests
Social Me: about.me - Twitter
Please use plain text.
Developer
UberschallSamsara
Posts: 920
Registered: ‎12-29-2010
My Device: PlayBook, Z10 LE, Dev Alpha C

Re: Passing Arguments to a Custom CellRender

[ Edited ]

The API is looking for a class, not an object, when you set the cellrenderer property.

 

The cell renderer has a data property which you can inspect to get the label data.  

This property gets populated by the list's data provider.

 

To add your 2nd custom label you can create it as an object property of your data provider

array elements.  Something like:

 

arrMonth.push({label: "January", customlabel: "Custom label text"});
arrMonth.push({label: "February", customlabel: "Custom label text"});

The data provider is an array of object literals value objects (which can be object literals) with

properties you can define.  The class expects a property called label, but you can add your own

object properties here. 

 

Then in your cell renderer, you can reference 

 

this.data.customlabel

 

to get to the custom label data.

Please use plain text.
Developer
nathanpc
Posts: 134
Registered: ‎05-19-2012
My Device: Torch 9800, PlayBook 64GB, Dev Alpha
My Carrier: VIVO Brazil

Re: Passing Arguments to a Custom CellRender

Thanks very much, it's working. Also thanks for teaching me a bit more about how to customize things in ActionScript. :smileyhappy:
If I helped you please click the "Like" button to support my work.
My apps: CherryNotes - Bookmarked - Requests
Social Me: about.me - Twitter
Please use plain text.
Developer
UberschallSamsara
Posts: 920
Registered: ‎12-29-2010
My Device: PlayBook, Z10 LE, Dev Alpha C

Re: Passing Arguments to a Custom CellRender

BTW it's been a while since I last wrote a custom cell renderer; it may be that you also need to override

the protected drawLabel() method in the cell renderer to insure your custom label gets properly redrawn

whenever you scroll up and down through a list that is longer than its viewport.  IIRC I had to do this to

set a checkbox property within the cell renderer.

Please use plain text.
Developer
nathanpc
Posts: 134
Registered: ‎05-19-2012
My Device: Torch 9800, PlayBook 64GB, Dev Alpha
My Carrier: VIVO Brazil

Re: Passing Arguments to a Custom CellRender

[ Edited ]

I did what you said, but now I'm getting this error:

 

TypeError: Error #1009: Cannot access a property or method of a null object reference.
	at views::TwoLabelCell/init()[/Users/Nathan/Documents/Adobe Flash Builder 4.6/AIRTest/src/views/TwoLabelCell.as:27]

Any ideas?

If I helped you please click the "Like" button to support my work.
My apps: CherryNotes - Bookmarked - Requests
Social Me: about.me - Twitter
Please use plain text.
Developer
jtegen
Posts: 6,541
Registered: ‎10-27-2010
My Device: HTC One, PlayBook, LE Z10, DE Q10
My Carrier: Verizon

Re: Passing Arguments to a Custom CellRender

You also need to override onAdded() and onRemoved() methods to add and remove your element from the display list. That does not get done in the init() fuinction.

What is at line 27?
Please use plain text.
Developer
nathanpc
Posts: 134
Registered: ‎05-19-2012
My Device: Torch 9800, PlayBook 64GB, Dev Alpha
My Carrier: VIVO Brazil

Re: Passing Arguments to a Custom CellRender

[ Edited ]

I've just implemented the overrides to onAdded and onRemoved like this, is it correct?

 

override protected function onAdded():void {
    super.onAdded();
}
		
override protected function onRemoved():void {
    super.onRemoved();
}

Here's what's at line 27:

 

description.text = this.data.secondLabel;

 

If I helped you please click the "Like" button to support my work.
My apps: CherryNotes - Bookmarked - Requests
Social Me: about.me - Twitter
Please use plain text.
Developer
jtegen
Posts: 6,541
Registered: ‎10-27-2010
My Device: HTC One, PlayBook, LE Z10, DE Q10
My Carrier: Verizon

Re: Passing Arguments to a Custom CellRender

Almost:

override protected function onAdded():void

{
    super.onAdded();

  this.addChild( this.description);
}

override protected function onRemoved():void

{
    super.onRemoved();

  this.removeChild( this.description);
}

 

And take it out of the init() function;

 

You have to test data since it can be called and it be null.  I typically:

 

if( this.data != null && this.data.hasOwnProperty( 'secondLabel' ) )

{

  this.description.text = this.data.secondLabel;

}

Please use plain text.