Understanding insert row behaviour in tableview

This is a question about understanding what is going on. I do know how to get the result I require.

In the attached code, if line 27 ( row.insert(row.bg) ) is commented out, the first row only of the table gets overlaid with the background cover. If line 27 is included, everything works as I would expect. My questions:

  1. Why does the row background get inserted at all without a _row.inser_t statement

  2. Why does it appear on top of the text ?

  3. Given that it does get inserted, why only on the first iteration of the insertRow loop?

[lua]

widget = require “widget”

_CH = display.contentHeight

_CW = display.contentWidth

local t = {}

t = {

{ name = “row1”, data = “data1”} ,

{ name = “row2”, data = “data2”} ,

{ name = “row3”, dta = “data3”} ,

}

local function onRowRender(event)

local row = event.row

local rowHeight = row.contentHeight

row.bg = display.newRect(0, 0, _CW, rowHeight)

row.bg.anchorX = 0 

row.bg.anchorY = 0

row.bg:setFillColor(1, 0.5, 1, 0.5)

– without the next statement - the 1st row is overlaid with row.bg

– row:insert(row.bg)

row.nameText = display.newText(

row, row.params.name, 20 , 0, nil, 12)

row.nameText.anchorX =0 

row.nameText.x = 10 ; row.nameText.y = rowHeight/2

row.nameText:setFillColor(0)

end

local tableView = widget.newTableView {

height = _CH/2 ,

onRowRender = onRowRender

}

– insert data

for i = 1, 3 do

tableView:insertRow {

rowHeight= 50 ,

params = {

name = t[i].name 

}

}

end

[/lua]

  1. Why does the row background get inserted at all without a _row.inser_t statement?

It doesn’t get inserted at all (except into the root display group) - it’s getting placed on top of the row first to be render.

 

  1. Why does it appear on top of the text?

Because it is outside the row group.

 

  1. Given that it does get inserted, why only on the first iteration of the insertRow loop?

Bear in mind there are 3 bg rects being created… Because none of them get inserted into any row’s group, they are being rendered in the root display group, which is display.currentStage. They all get rendered in the same location, because they all have the same 0,0 reference point. The bg’s look are being rendered on top of the text, but that is an illusion because they are being rendered on top of the whole table view. To understand this, you need to understand where in the root display group the various objects are being rendered. Without inserting the bg object into each row (this is the commented out line, or - and this is the better option - providing the newRect with a parent parameter) the order is: table view, then three rect’s - so those appear on top, but at the same location.

local widget = require "widget" \_CH = display.contentHeight \_CW = display.contentWidth local t = {} t = { { name = "row1", data = "data1"} , { name = "row2", data = "data2"} , { name = "row3", dta = "data3"} , } local function onRowRender(event) local row = event.row local rowHeight = row.contentHeight row.bg = display.newRect( row, \_CW/2, rowHeight/2, \_CW, rowHeight) row.bg.fill = { 1, 0.5, 1, 0.5 } row.nameText = display.newText{ parent=row, text=row.params.name, x=10, y=rowHeight/2, fontSize=12 } row.nameText.x = row.nameText.x + row.nameText.width/2 row.nameText:setFillColor(0) end local tableView = widget.newTableView { height = \_CH/2, onRowRender = onRowRender } -- insert data for i = 1, 3 do tableView:insertRow { rowHeight= 50, params = { name = t[i].name } } end

I have updated the code to render what I believe you are after but with some adjustments for the most recent use case of newRect and newText. Also, I prefer avoiding changing the anchor value of an object (personal pref, I suppose) and have changed that to simply move the text.

At the end of the day the row is just a display.newGroup(). You have to do a row:insert() on any display.* object you create that belongs with that row. Technically you don’t have to do:

row.title = display.newText(...) row:insert( row.title)

You could do:

local title = display.newTitle(...) row:insert( title )

and accomplish the same thing. The reason the samples show using row.bg is so you can have an easy reference to the members inside the onRowTouch function. In that function you get a reference to the row object. You could traverse the row looking for the objects but its just easier to reference it as:

row.title.text = "New text"

in the onRowTouch() function.

Rob

Cheers for the replies.

My problem was not understanding the concept of the root display. Al makes perfect sense now

  1. Why does the row background get inserted at all without a _row.inser_t statement?

It doesn’t get inserted at all (except into the root display group) - it’s getting placed on top of the row first to be render.

 

  1. Why does it appear on top of the text?

Because it is outside the row group.

 

  1. Given that it does get inserted, why only on the first iteration of the insertRow loop?

Bear in mind there are 3 bg rects being created… Because none of them get inserted into any row’s group, they are being rendered in the root display group, which is display.currentStage. They all get rendered in the same location, because they all have the same 0,0 reference point. The bg’s look are being rendered on top of the text, but that is an illusion because they are being rendered on top of the whole table view. To understand this, you need to understand where in the root display group the various objects are being rendered. Without inserting the bg object into each row (this is the commented out line, or - and this is the better option - providing the newRect with a parent parameter) the order is: table view, then three rect’s - so those appear on top, but at the same location.

local widget = require "widget" \_CH = display.contentHeight \_CW = display.contentWidth local t = {} t = { { name = "row1", data = "data1"} , { name = "row2", data = "data2"} , { name = "row3", dta = "data3"} , } local function onRowRender(event) local row = event.row local rowHeight = row.contentHeight row.bg = display.newRect( row, \_CW/2, rowHeight/2, \_CW, rowHeight) row.bg.fill = { 1, 0.5, 1, 0.5 } row.nameText = display.newText{ parent=row, text=row.params.name, x=10, y=rowHeight/2, fontSize=12 } row.nameText.x = row.nameText.x + row.nameText.width/2 row.nameText:setFillColor(0) end local tableView = widget.newTableView { height = \_CH/2, onRowRender = onRowRender } -- insert data for i = 1, 3 do tableView:insertRow { rowHeight= 50, params = { name = t[i].name } } end

I have updated the code to render what I believe you are after but with some adjustments for the most recent use case of newRect and newText. Also, I prefer avoiding changing the anchor value of an object (personal pref, I suppose) and have changed that to simply move the text.

At the end of the day the row is just a display.newGroup(). You have to do a row:insert() on any display.* object you create that belongs with that row. Technically you don’t have to do:

row.title = display.newText(...) row:insert( row.title)

You could do:

local title = display.newTitle(...) row:insert( title )

and accomplish the same thing. The reason the samples show using row.bg is so you can have an easy reference to the members inside the onRowTouch function. In that function you get a reference to the row object. You could traverse the row looking for the objects but its just easier to reference it as:

row.title.text = "New text"

in the onRowTouch() function.

Rob

Cheers for the replies.

My problem was not understanding the concept of the root display. Al makes perfect sense now