Android TableViewRow with className - images vanishes after scrolling!

You must Login before you can answer or comment on any questions.

Hi all,

I have an app that uses tableViewRow, with an imageView (external URL) and text label - with a className.

When it first load, the images appear fine but when I scroll down and then up again, the loaded images disappears??

I noticed if I remove className, the images stay but I need the className for performance. Or else it is just way too laggy.

Anyone faced this before? Really appreciate any help!

Code section that does this:

...
 
var imagelabel = Ti.UI.createView({
                height: 75,
                backgroundColor:'#000',
                left:0,
                width:98,   
            });
 
            bandThumbnail[c] =  Titanium.UI.createImageView({
                image: 'images/image-na-large.png',
                width:98,   
                backgroundColor:'#000'
 
            });
            imagelabel.add(bandThumbnail[c]);
            getExternalImage(title, 'large',bandThumbnail[c]);
 
 
            var label = Ti.UI.createLabel({
                text:title,
 
                font:{fontSize:16,fontWeight:'bold'},
                color:'#FFFFFF',
                textAlign:'left',
                top:5,
                left:110,
                width:185,
                height:25   
            });
 
            if(isAndroid){
                label.wordWrap = false;
            }
 
            var gigVenueLabel =  Titanium.UI.createLabel({
 
                text:venueTown + ", " + venueName,
                font:{fontSize:12,fontWeight:'bold'},
                width:'auto',
                color:'#ff0000',
                textAlign:'left',
                top:30,
                left:110,
                width:180,
                height:20
            });
 
            var gigDate =  Titanium.UI.createLabel({
                text:gigDate,
                font:{fontSize:12,fontWeight:'bold'},
                color:'#FFFFFF',
                textAlign:'left',
                top:48,
                left:110,
                width:190,
                height:20
            });
 
            var row = Ti.UI.createTableViewRow({index:c, height:75,top:0,backgroundImage: './images/640x960/itemrow.png',selectedBackgroundColor:'#000'});
...

— asked 8 months ago by Terenze Yuen
7 Comments
  • I've noticed the same exact problem...!

    — commented 8 months ago by Michael Belkin

  • Still no help??

    — commented 8 months ago by Terenze Yuen

  • Hm...anyone guys?

    — commented 8 months ago by Terenze Yuen

  • Show 4 more comments

3 Answers

So... this was a tough one. Digging into the Ti core I found that iOS has remote image caching built in, but not for Android. I used this as a reference to some luck: inline link text. I changed the logic to require and not include, then made module commonJS style. Be careful with your eventlisteners and watch your logcat.

/**
 * download remote images in a single thread
 *
 * @category   Titanium
 * @package    Snippets
 * @copyright  Copyright (c) 2011 Mario Micklisch
 * @license    http://framework.zend.com/license/new-bsd     New BSD License
 */
Ti.API.debug('PENTON - RemoteImageView.js');
 
exports.createRemoteImageView = function(options) {
    Ti.API.debug('RemoteImageView.js::createRemoteImageView');
    // check for cached local file
    var imageUrl = options.image;
    var cacheFilename = imageUrl.replace(/[^a-zA-Z0-9\.]/ig, '_');
    var cacheFile = Ti.Filesystem.getFile(Ti.Filesystem.applicationDataDirectory, cacheFilename);
 
    // create the basic object without image url
    delete (options.image);
    var remoteImage = Titanium.UI.createImageView(options);
 
    // check for cached version
    var cacheFileModDate = cacheFile.modificationTimestamp();
    var dateToCompare = (new Date()).getTime() - 86400;
 
    if (cacheFile.exists() && cacheFileModDate < dateToCompare) {
        remoteImage.image = cacheFile.nativePath;
        Ti.API.debug('RemoteImageView.js - Cached image!!');
    } else {
        if (cacheFile.exists()) {
           Ti.API.debug('RemoteImageView.js - Did NOT cache image! Cache File DOES exist');
           Ti.API.debug('RemoteImageView.js - cacheFileModDate = ' + cacheFileModDate);
            Ti.API.debug('RemoteImageView.js - dateToCompare = ' + dateToCompare);  
        } else {
            Ti.API.debug('RemoteImageView.js - Did NOT cache image!!');
        }
 
 
        if (options.defaultImage) {
            remoteImage.image = options.defaultImage;
        }
 
        var cacheListener = function(e) {
            remoteImage.image = e.filename;
            Ti.App.removeEventListener("dl_" + cacheFilename, cacheListener);
            Ti.API.debug('RemoteImageView.js - Removed event listener');
        };
 
        Ti.App.addEventListener("dl_" + cacheFilename, cacheListener);
 
        Ti.App.fireEvent("dl_image", {
            imageUrl : imageUrl,
            eventId : "dl_" + cacheFilename
        });
    }
 
    return remoteImage;
}
/**
 * for easier use:
 * Ti.UI.createRemoteImageView
 * Titamium.UI.createRemoteImageView
 * points to createRemoteImageView
 */
//Ti.UI.createRemoteImageView = Titanium.UI.createRemoteImageView = createRemoteImageView;
 
/**
 * create imageview listener on first include
 */
 
//exports.addRemoteImageViewListener = function() {
 
    //if (!Ti.App.hasRemoteImageViewListener) {
    if (!Ti.App._has_remote_image_view_listener) {
        Ti.API.info('RemoteImageView.js::addRemoteImageViewListner - adding event listener for remote images');
        Ti.App.cacheLifetime = 86400;
        Ti.App.addEventListener("dl_image", function(e) {
            var imageUrl = e.imageUrl;
            var eventId = e.eventId;
            var cacheFilename = imageUrl.replace(/[^a-zA-Z0-9\.]/ig, '_');
            var cacheFile = Ti.Filesystem.getFile(Ti.Filesystem.applicationDataDirectory, cacheFilename);
 
            var xhr = Ti.Network.createHTTPClient({
                onload : function(e) {
                    Ti.API.debug('RemoteImageView.js: - xhr.onload');
                    if (xhr.status == 200) {
                        try {
                            Ti.API.info('RemoteImageView.js: - xhr.status == 200');
                            Ti.API.info("RemoteImageView.js: - xhr.responseData: " + xhr.responseData);
                            Ti.API.info("RemoteImageView.js: - xhr.readyState: " + xhr.readyState);
                            // cache the file
                            cacheFile.write(xhr.responseData);
 
                            // assign the image
                            Ti.App.fireEvent(eventId, {
                                filename : cacheFile.nativePath
                            });
                        } catch (e) {
                            Ti.API.warn('RemoteImageView.js::adRemoteImageViewListener - XHR Status != 200.  Error: ' + e);
                        }
                    };
                },
                onerror : function(e) {
                    Ti.API.info('RemoteImageView.js: XHR error - image retireval not successful');
                },
                timeout : 1000,
            });
 
            // cache overwrite
            if (imageUrl.indexOf('?') > 0) {
                imageUrl += '&' + new Date().getTime();
            } else {
                imageUrl += '?' + new Date().getTime();
            }
 
            // send the request
            xhr.open('GET', imageUrl);
            if (Ti.Network.online) {
              xhr.send();   
            }
 
            Ti.App._has_remote_image_view_listener = true;
 
        });
    }
//}
then I called it like this:
if (OS_ANDROID) {
    var remoteImage = require('RemoteImageView');
        //var mainView = Ti.UI.createImageView({ // origonal before using remote caching
        var mainView = remoteImage.createRemoteImageView({
            image : theImageLink,
            width : Ti.UI.FILL,
            height : Ti.UI.FILL,
    });
}
I think this should work, or at least get you far. Check out the link above. I might not be back to this thread for awhile, so good luck!

— answered 2 months ago by Steven House
answer permalink
1 Comment
  • Hi Steven, Your code work perfectly for me on an android device. Thank you for sharing !!!

    — commented 5 weeks ago by Goh Ten Fatt

I'm removed classname property and my problem is solved.

But now the images refreshs when I scroll the table view or I add a new columns dinamicaly.

This is a new error. With previous SDK's it didn't happen.

Your Answer

Think you can help? Login to answer this question!