Tagged as

Skinning PlayBook Components

There are basically three ways you can skin components on the PlayBook: with a Flash Professional SWC that contains the graphic objects, with images, and using the AS3 drawing API. I’ll show off the last two.

I've been having a lot of fun with the PlayBook. It's really nice to be using ActionScript 3 to write a “native” application and the QNX components have been really good. One of the things I wanted to do right away was skin them to customize them for the Pintley app I'm building. Luckily, if you've spent any time doing Flash, it's pretty straightforward. The main issue is that the SDK is still fairly new so there were some small things I had to figure out.

Skinning with Images

What I wanted to do was skin a TextInput and a Button for my login page. The PlayBook SDK has a few classes that are specifically for skinning, which I was able to check out via the documentation. There's an entire package qnx.ui.skins that has classes for skinning. It looks like, based on this page, that most of the default skins, are images. So I tried that first. What I found helpful was to grab those stock images, bring them into Photoshop, and start tweaking them.

I create three different PNGs for each of the states the TextInput has: up, down, and focus. Once I have those, I embed them in my custom skin class and use the specific QNX APIs to set the look and feel. The class extends the qnx.ui.skins.text.TextInputSkin class, which is the base class for creating a TextInputSkin. Using the attributes on the Embed tag you can set the numbers to make the nine-slice scaling work for your image.

The method to override is the initializeStates method. That's the best place to register properties for states with the QNX component model. Then there are two other methods to use in that method. The first one, setSkinState, just associates a specific skin with a specific state. The last line of code, showSkin, takes a skin class and that's what the component will use as the default skin.

Skinning with the Drawing API

Another way to skin the components is using the drawing API. This one is mostly similar to using images with a couple of minor changes. Create the variables in the same way, and override the initializeStates function. Skinning with the drawing API also uses the same methods as the images. setSkinState works the same way and showSkin sets the default skin.

The main difference is that there is an external function in this example, which is where the drawing takes place. Since the different states of the component will look generally the same, I pass in some variables to change the appearance based on which state it's being drawn for. The method gets called in the initializeStates function after the skin sprites are initialized. You could also just do the drawing in the initializeStates method, but this is a bit better in terms of code reuse.

One last example that I have uses the image method but skins a button instead of the TextInput control. One thing I've noticed about the QNX controls is that some of the components (like TextInput) have their own skin files that can be subclassed, while others, like Buttons, have skins that look like they just subclass UISkin. So instead of calling super.initializeStates() like I did with the TextInput, with the Button, I just override initializeStates() and put the code there.

Update: Thanks to a comment below, I realized that when you extend UISkin, the skinned objects have to be of type DisplayObject, not Sprite.