Jump to content

[TOPIC: topicViewTemplate]
[GLOBAL: userSmallPhoto]
Photo

Loading async images and Tableview
Started by pedro.perina Aug 20 2013 06:10 AM

- - - - -
4 replies to this topic

Best Answer jonjonsson , 20 August 2013 - 03:22 PM

I recommend trying to do what Brent is suggesting but if not it is possible with some workarounds.

 

Basically these steps:

 

In rowRender use network.download instead of loadRemoteImage. 

 

In network.download listener you need to check if the row is currently rendered (off screen rows are not rendered). If it is rendered, you render the image.

 

It would make sense to cache the image once it is downloaded. So when a row is rerendered it will not re-download it.

 

Please see my reply to this post on how to update table dynamically: http://forums.coronalabs.com/topic/36881-tableview-how-to-force-re-rendering/

 

Edit: It occurred to me that maybe row rerender function is available now, in that case you can use that in your network listener. It would simplify this a bit. I'm not finding it in docs though: http://docs.coronalabs.com/daily/api/type/TableViewWidget/index.html

[TOPIC CONTROLS]
[/TOPIC CONTROLS]
[modOptionsDropdown]
[/modOptionsDropdown]
[reputationFilter]
[TOPIC: post.html]
#1

pedro.perina

[GLOBAL: userInfoPane.html]
pedro.perina
  • Starter
  • PipPipPip
  • 31 posts
  • Advanced Member

Hi,

 

I'm trying to load images from the internet and, once they are loaded, insert them into a tableview row. Everything is working almost as expected. The problem comes up when the user scrolls the tableview too fast. In this case, some of the images are not inserted in the row, but in the top of the screen. It seems the row is somehow not valid anymore in these cases, maybe there is some kind of recycling done by the library, I don't know.

This is the code:

local function onRowRender(event)
	local row = event.row
	local function networkListener(event)
		if ( event.isError ) then
			print ( "Network error - download failed" )
		else			
			event.target.x = 71;
			event.target.y = row.contentHeight * 0.5 - 3;
			row:insert(event.target);
		end
	end
	display.loadRemoteImage( "http://blablabla", "GET", networkListener, blabla..".jpg");
end

 

Is there something wrong here?

 

Thanks a lot



[TOPIC: post.html]
#2

Brent Sorrentino

[GLOBAL: userInfoPane.html]
Brent Sorrentino
  • Corona Staff
  • 3,940 posts
  • Jedi

Hi @pedro.perina,

TableView dynamically populates rows on and off the screen, so if you're moving this very fast and attempting to do network downloads at the same time, the rows will not always update fast enough (because the images are downloading). If possible, I suggest that you pre-load these images.

 

Hope this helps,

Brent Sorrentino



[TOPIC: post.html]
#3

jonjonsson

[GLOBAL: userInfoPane.html]
jonjonsson
  • Pro
  • PipPipPipPipPipPip
  • 797 posts
  • Jedi

  Best Answer

I recommend trying to do what Brent is suggesting but if not it is possible with some workarounds.

 

Basically these steps:

 

In rowRender use network.download instead of loadRemoteImage. 

 

In network.download listener you need to check if the row is currently rendered (off screen rows are not rendered). If it is rendered, you render the image.

 

It would make sense to cache the image once it is downloaded. So when a row is rerendered it will not re-download it.

 

Please see my reply to this post on how to update table dynamically: http://forums.coronalabs.com/topic/36881-tableview-how-to-force-re-rendering/

 

Edit: It occurred to me that maybe row rerender function is available now, in that case you can use that in your network listener. It would simplify this a bit. I'm not finding it in docs though: http://docs.coronalabs.com/daily/api/type/TableViewWidget/index.html



[TOPIC: post.html]
#4

ksan

[GLOBAL: userInfoPane.html]
ksan
  • Pro
  • PipPipPipPipPipPip
  • 2,604 posts
  • Jedi

See the following thread and some great code Mpappas generously shared doing exactly what you're after. The discussion about image loading into the tableView was a little offTopic so you will need to read through the thread. 

 

http://forums.coronalabs.com/topic/33185-widget-20-tableview-performance/page-3



[TOPIC: post.html]
#5

pedro.perina

[GLOBAL: userInfoPane.html]
pedro.perina
  • Starter
  • PipPipPip
  • 31 posts
  • Advanced Member

Great! Thanks a lot for the great support. After looking at the threads pointed out above, I ended up opting to use jonjonsson's solution (hack). I will post my code here if others get stuck at the same point (just removed the cache section for the sake of simplicity.

 

 

 

br,

Cleverson

	local updateTableRows = function()
		local tableViewRows = tableView._view._rows
		for k, row in ipairs(tableViewRows) do
			if (row.imageObject) then
				display.remove(row.imageObject);
			end
			if (row._view) then
				local img = display.newImage("myImage.jpg",system.TemporaryDirectory)
				img.x = 71;
				img.y = 40;
				row._view:insert(img);
				row.imageObject = img;
			end
		end
	end

	local function onRowRender(event)
		local row = event.row
		local function networkListener(event)
			if ( event.isError ) then
				print ( "Network error - download failed" )
			else
				display.remove(event.target);
				event.target = nil;
				updateTableRows();
			end
		end
		display.loadRemoteImage( "http://myImage", "GET", networkListener, "myImage.jpg", system.TemporaryDirectory);
	end



[topic_controls]
[/topic_controls]