TableView Rows - Add an Image

How can I add  different images to each row of a TableView. I have been using the TableView found in the WidgetDemo but need some guidance on how to proceed. 

A few years ago Corona had an example called :

“Create scrolling list views with text and graphics in Corona”

http://www.coronalabs.com/blog/2010/09/24/create-scrolling-list-views-with-text-and-graphics-in-coronasdk-ios-android-tutorial/

I would like to have that same functionality with the Widget TableView.

When you create a widget.newTableView() you define three helper functions, one of them is called “onRowRender”.  This function will draw a single row of the table view.  The row is in effect a display group so you can create images using display.newImageRect() and then insert it into the group like you would any other display group.

There is a function called tableView:insertRow() that sets some properties for the row, including an index variable, but this basically triggers the onRowRender function if that row is on screen.  Inside of your onRowRender() function, you can get that index variable and then look up data in other tables to determine what goes in that individual row.

Look up the docs for widget.newTableView and also look back in the blog to the beginning of the year to the New Blog Widgets part 2 tutorial.

When you create a widget.newTableView() you define three helper functions, one of them is called “onRowRender”.  This function will draw a single row of the table view.  The row is in effect a display group so you can create images using display.newImageRect() and then insert it into the group like you would any other display group.

There is a function called tableView:insertRow() that sets some properties for the row, including an index variable, but this basically triggers the onRowRender function if that row is on screen.  Inside of your onRowRender() function, you can get that index variable and then look up data in other tables to determine what goes in that individual row.

Look up the docs for widget.newTableView and also look back in the blog to the beginning of the year to the New Blog Widgets part 2 tutorial.

Part 3 has the code snippet from docs for onRowRender, I guess that’s the one you meant :slight_smile:

If only 1 tableView example had images in onRowRender, it would save a lot of questions.

Some of the things that are not apparent from examples and docs is why rowTitle.y=row.contentheight*0.5, but creating a newImageRect and giving it the exact same y puts all rows’ images at the top of the screen - and adding row.y to it “fixes” things, sort of, but they’re not offset by the table top edge and you find you have to NOT add the row.contentheight*0.5!

What is magical about a newText in onRowRender, ie. how come you must calculate the y manually to all other displayObjects?? (For which I don’t I don’t have to add contentHeight*0.5, by the way.)

Note that you don’t have access to tableView.y to add it - unless you store it in a variable outside the onRowRender scope.

My problem right now is that the images don’t move with the rows when the tableView is dragged…

henrik, it sounds like you aren’t inserting the text into the row before setting it’s coordinates.

In your onRowRender, you get a pointer to the rows display group:

    local row = event.row

And after your create the text (or any other object like a photo), insert it into the row:

    row:insert( messageText )

Changes to the objects coords are now relative to the row groups coords (0,0 being top left of the row I believe).

Yes, that worked. Thanks :slight_smile:

But the newText is still magical, because I had no row:insert whatever in my code, since it’s not in the docs or examples.

So now for me this has been reduced to mere curiosity as to why some displayObjects seemingly get inserted automatically. (I even renamed the displayObject to rowTitle2 to test, and it doesn’t go by the name of it anyway.)

local rowTitle = display.newText( row, "Row " .. row.index, 0, 0, nil, 14 )

row (first argument) is the parent group and means nothing else then

row:insert(rowTitle)

… so no magic here :slight_smile:

Part 3 has the code snippet from docs for onRowRender, I guess that’s the one you meant :slight_smile:

If only 1 tableView example had images in onRowRender, it would save a lot of questions.

Some of the things that are not apparent from examples and docs is why rowTitle.y=row.contentheight*0.5, but creating a newImageRect and giving it the exact same y puts all rows’ images at the top of the screen - and adding row.y to it “fixes” things, sort of, but they’re not offset by the table top edge and you find you have to NOT add the row.contentheight*0.5!

What is magical about a newText in onRowRender, ie. how come you must calculate the y manually to all other displayObjects?? (For which I don’t I don’t have to add contentHeight*0.5, by the way.)

Note that you don’t have access to tableView.y to add it - unless you store it in a variable outside the onRowRender scope.

My problem right now is that the images don’t move with the rows when the tableView is dragged…

henrik, it sounds like you aren’t inserting the text into the row before setting it’s coordinates.

In your onRowRender, you get a pointer to the rows display group:

    local row = event.row

And after your create the text (or any other object like a photo), insert it into the row:

    row:insert( messageText )

Changes to the objects coords are now relative to the row groups coords (0,0 being top left of the row I believe).

Yes, that worked. Thanks :slight_smile:

But the newText is still magical, because I had no row:insert whatever in my code, since it’s not in the docs or examples.

So now for me this has been reduced to mere curiosity as to why some displayObjects seemingly get inserted automatically. (I even renamed the displayObject to rowTitle2 to test, and it doesn’t go by the name of it anyway.)

local rowTitle = display.newText( row, "Row " .. row.index, 0, 0, nil, 14 )

row (first argument) is the parent group and means nothing else then

row:insert(rowTitle)

… so no magic here :slight_smile:

I’m having trouble figuring out how to go about inserting display groups to TableView rows. 

I’ve read the thread above carefully, but I’m still not getting it.

I also looked at Corona documentation:

http://docs.coronalabs.com/api/library/widget/newTableView.html

http://docs.coronalabs.com/api/type/TableViewWidget/insertRow.html

Sample code that comes bundled with Corona SDK does not offer any insight as to what I need to do either.

So, as autolib noted up top, I feel Corona hasn’t really offered any documentation or sample code anywhere  that could help us – or perhaps they are so very hidden that I’ve failed to find them, or I just don’t know what to look for – so here I am, still no solution in sight.

Here’s what I’ve tried.  Clearly, I’m missing something, but I don’t know what that is:

[lua]

– localGroup is self.view in composer

– myTable is a local variable forward referenced up top

local imageGroup = {}

local onRowRender = function()

    --[[

    Here I created display groups:

        imageGroup[1]

        imageGroup[2]

        imageGroup[3]

        imageGroup[4]

        imageGroup[5]

        Each of these display groups has 4 pieces of display objects inside

    --]]

    local row = event.row

    local rowH = row.contentHeight

    local rowW = row.contentWidth

    for i=1,5 do

        myTable:insertRow{

            rowHeight = 55

        }

        row:insert( imageGroup[i] )

    end

end

local onRowTouch = function()

    – do whatever needs to be done onRowTouch

end

myTable = widget.newTableView

{

    width = 230, 

    height = 240,

    backgroundColor = { 0.9, 0.9, 0.9 },

    hideBackground = false,

    onRowRender = onRowRender,

    onRowTouch = onRowTouch,

}

localGroup:insert( myTable )

myTable.x = display.contentCenterX-120;  myTable.y = display.contentCenterY+20

[/lua]

Why don’t I see the display groups neatly appearing in row inside the TableView object?  What am I missing?  Could it be possible that TableView cannot hold display groups – could it be the reason why my attempt would never work?

I’d so appreciate any help anyone can offer.

Naomi

please post your onRowRender function. Then we can se what is going on.

I don’t know what happened to the code…  formatting got so messed up (although, in editing mode, it looks fine.)

So here’s the copy of the same code.  Hopefully, it won’t get messed up:

[lua]

– localGroup is self.view in composer

– myTable is a local variable forward referenced up top

local imageGroup = {}

local onRowRender = function()

    --[[

    Here I created display groups:

        imageGroup[1]

        imageGroup[2]

        imageGroup[3]

        imageGroup[4]

        imageGroup[5]

        Each of these display groups has 4 pieces of display objects inside

    --]]

    local row = event.row

    local rowH = row.contentHeight

    local rowW = row.contentWidth

    for i=1,5 do

        myTable:insertRow{

            rowHeight = 55

        }

        row:insert( imageGroup[i] )

    end

end

local onRowTouch = function()

    – do whatever needs to be done onRowTouch

end

myTable = widget.newTableView

{

    width = 230, 

    height = 240,

    backgroundColor = { 0.9, 0.9, 0.9 },

    hideBackground = false,

    onRowRender = onRowRender,

    onRowTouch = onRowTouch,

}

localGroup:insert( myTable )

myTable.x = display.contentCenterX-120;  myTable.y = display.contentCenterY+20

[/lua]

Ah yes. You are inserting rows in your onRowRender function. You are only supposed to add objects to the rows view which is event.row in the onRowRender function.

You should insert the rows outside of that function after you ave created the tableView.

Also note that onRowRender is called once for each row so only insert elements for one row at a time.

Thank you, @primoz.cerar – but I’m afraid I fail to understand what you mean?

What does it mean to “add objects to the rows view, which is event.row in the onRowRender function” – and what does it also mean to “insert the rows outside of that function”…?  Sorry for not getting it, but I still don’t understand.

Hmmm… add display groups to the rows view – which is event.row in the onRowRender function – but then I need to insert the rows outside of onRowRender function.  I’m confused.

Naomi

 -- localGroup is self.view in composer -- myTable is a local variable forward referenced up top local imageGroup = {} local onRowRender = function() --[[Here I created display groups: imageGroup[1] imageGroup[2] imageGroup[3] imageGroup[4] imageGroup[5] Each of these display groups has 4 pieces of display objects inside --]] local row = event.row local rowH = row.contentHeight local rowW = row.contentWidth -- just add the elements of the current row being rendered. Mind that indexes are not continuous if you delete rows row:insert( imageGroup[row.index] ) end local onRowTouch = function() -- do whatever needs to be done onRowTouch end myTable = widget.newTableView { width = 230, height = 240, backgroundColor = { 0.9, 0.9, 0.9 }, hideBackground = false, onRowRender = onRowRender, onRowTouch = onRowTouch, } localGroup:insert( myTable ) myTable.x = display.contentCenterX-120; img.table.y = display.contentCenterY+20 --insert rows here for i=1,5 do myTable:insertRow{ rowHeight = 55 } end

Hope this helps

Ah, thank you so much, @primoz.cerar!!  Super appreciated.

Naomi

It looks like I need to create display groups (imageGroup[1], imageGroup[2], etc) before I create the table inside the scene:create function of the composer, but they are now at least appearing inside the table.  Next I have to figure out how to properly position them inside the row (right now, half of it gets cut off to the left) – but at least I’m half way there.

Thanks again, @primoz.cerar!

Cheers,

Naomi

You’re welcome.

I’m not sure when exactly the first on render row is called but i imagine it’s on insertRow so make sure your groups are set up before that.

As for positioning that all depends on your group set up. Check what you set for anchorX and anchorY and position accordingly. I believe the coordinates in the row view are center based so if you have anchorX = 0.5 (default) on your group, to center it, you should position it on x = row.contentWidth * 0.5

I may be wrong here but you will figure it out.