01-14-2011 05:00 AM
There isn't a lot of information about the QNX UI classes so I figured this would be good to post here for those wanting to do some List/Image optimizations.
Using QNX Image and ImageCache in List Custom CellRenderer
http://renaun.com/blog/2011/01/using-qnx-image-and
The custom cell renderer in the post above looks like this (all source code available at (https://github.com/renaun/QNXListImageCache):
package com.renaun.renderer
{
import flash.display.Sprite;
import flash.text.TextFieldAutoSize;
import flash.text.TextFormat;
import qnx.ui.display.Image;
import qnx.ui.listClasses.CellRenderer;
import qnx.ui.text.Label;
import qnx.utils.ImageCache;
public class CacheImageCellRenderer extends CellRenderer
{
/**
* This is a static cache object. Alternatively you can
* create this object out side this class to be used
* in more then one place.
*/
public static var cacheObject:ImageCache = new ImageCache();
public function CacheImageCellRenderer()
{
super();
initBackground();
}
/**
*
*/
protected var img:Image;
protected var lbl:Label;
protected var bg:Sprite;
protected var format:TextFormat;
/**
* Updates the text and image everytime a new data is set
* for this renderer instance.
*/
override public function set data(value:Object):void
{
super.data = value.data;
//trace(value.data.text + " - " + value.data.url);
updateCell();
}
/**
* Update the image and text if there is valid data.
*/
private function updateCell():void
{
if (this.data)
{
//trace("loading: " + data.url);
img.setImage(data.url);
lbl.text = data.text;
}
}
/**
* Create all the cell renderer components just once
*/
private function initBackground():void
{
img = new Image();
lbl = new Label();
bg = new Sprite();
format = new TextFormat();
format.color = 0xEEEEEE;
format.size = 12;
format.bold = true;
bg.graphics.clear();
bg.graphics.beginFill(0x000000, .7);
bg.graphics.drawRect(0, 0, 240, 50);
bg.graphics.endFill();
img.setPosition(0,0);
img.setSize(240,134);
// Setting the cache propery on QNX Image class
// takes care of adding and checking for images on
// the ImageCache object.
img.cache = CacheImageCellRenderer.cacheObject;
lbl.width = 240;
lbl.format = format;
lbl.wordWrap = true;
lbl.x = 5;
lbl.y = 0;
lbl.width = 220;
lbl.autoSize = TextFieldAutoSize.LEFT;
addChild(img);
addChild(bg);
addChild(lbl);
}
}
}
Check out the use of ImageCache, basically one instance of ImageCache set to each Image instance's cache property and Image class takes care of adding and getting cached images on the ImageCache instance.
01-16-2011 05:59 AM
Thanks Renaun. This helped me a lot !
01-17-2011 04:14 PM
thanks, saved me a ton of work because file.browse doesn't work.
01-27-2011 12:13 PM
i'm unfortunately getting errors with that code. it gives me this:
Error #2044: Unhandled ioError:. text=
i try to load 4 images. every time i start the debugger, it gives me o1, 2, 3, none or all of them
the images i've been trying to load were these:
loading: http://apps.n-tv.de/stat/apps/bb/sport.png
loading: http://apps.n-tv.de/stat/apps/bb/stock.png
loading: http://apps.n-tv.de/stat/apps/bb/fussballticker.pn
loading: http://apps.n-tv.de/stat/apps/bb/wirtschaft.png
all of them very small icons. at first i was thinking the images might be too large, but when i tried using a loader, it didn't show anything at all.
any help
? the code i'm using is this:
var dp2:DataProvider = new DataProvider(); var obj1:Object = new Object(); obj1.text = "Item 1"; obj1.url = "http://apps.n-tv.de/stat/apps/bb/sport.png"; dp2.addItem({label:obj1.text, data:obj1}); var obj2:Object = new Object(); obj2.text = "Item 2"; obj2.url = "http://apps.n-tv.de/stat/apps/bb/stock.png"; dp2.addItem({label:obj2.text, data:obj2}); var obj3:Object = new Object(); obj3.text = "Item 3"; obj3.url = "http://apps.n-tv.de/stat/apps/bb/fussballticker.png"; dp2.addItem({label:obj3.text, data:obj3}); var obj4:Object = new Object(); obj4.text = "Item 4"; obj4.url = "http://apps.n-tv.de/stat/apps/bb/wirtschaft.png"; dp2.addItem({label:obj4.text, data:obj4}); var list:List = new List(); list.x = 512; list.y = 200; list.height = 300; list.width = 400; list.setSkin(CacheImageCellRenderer); list.dataProvider = dp2; list.opaqueBackground = 0xFFFFFF; //setting the event for each of the items being clicked, this will load up in the web view in the getFeed event //list.addEventListener(ListEvent.ITEM_CLICKED, itemClickedHandler); addChild(list);
and your CacheImageCellRenderer class
01-27-2011 12:37 PM
Can we see the code for the renderer?
Have you tried embeddding the images instead of going to the web to access them? Will be faster and more reliable since the PB might not have an Internet connection all the time.
01-27-2011 12:40 PM
Ah, you're probably using the renderer earlier in the thread.
Try no using the cache mechnanism and just override onAdded and onRemoved to add and remove the image from the display.
Also, things that are more or less static, I tend to embed to make it faster and more reliable to load.
01-27-2011 04:04 PM
yes, i used the renderer of renaun. but having the images locally does not really help, because i wanted to have an rss-reader which also loads the images which you normally see in an rss-teaser-feed
i actually also tried to use a loader, but that didn'T work for me as well ![]()
removing the cache is possible. i'll give it a try tomorrow, right now i'm too tired ![]()
01-27-2011 07:22 PM
The ioError event usually is called when it can't find a url, or the url sends back a non-200 response.
You can add an event listener on the renderer's Image object and see what the message is.
Renaun
01-28-2011 03:44 AM - edited 01-28-2011 10:01 AM
you were right, the url's weren't found. here's what i've got:
with imagecache:
[IOErrorEvent type="ioError" bubbles=false cancelable=false eventPhase=2 text="" errorID=0]
without imagecache:
[IOErrorEvent type="ioError" bubbles=false cancelable=false eventPhase=2 text="Error #2035: URL Not Found. URL: http://apps.n-tv.de/stat/apps/bb/fussballticker.pn
[IOErrorEvent type="ioError" bubbles=false cancelable=false eventPhase=2 text="Error #2035: URL Not Found. URL: http://apps.n-tv.de/stat/apps/bb/wirtschaft.png" errorID=2035]
now this is getting funny. of course, i could add the same function call (img.setImage(data.url)) into the errorfunction like this (and add a counter for number of tries):
private function onIOError(e:IOErrorEvent):void
{
trace(e.toString());
img.setImage(data.url);
}but that's a hacky solution (though it works, of course). hmm. does anyone have a better idea for this? for now i'll retry to build a smarter loader, maybe the actionscript forums have a better idea
EDIT: i got an idea from another colleague for now: using a default image and leaving the onIOError function with a counter as it is
, so ifthe image was unable to be loaded within the fifth try, the default image will be shown. thanks for the help, everybody!
01-28-2011 11:07 AM
Its a good idea because network connectivity in the real world will change and having a default image scheme is a good approach.