Create scrolling list views with text and graphics in Corona

Share on Facebook0Share on Google+0Tweet about this on TwitterShare on LinkedIn0

We’ve created a set of mobile user interface frameworks that will give you a jumpstart on creating professional, touch screen apps in Corona.

In this article, I’ll show you how to add text, graphics, and custom behaviors to the List View.

The List View accepts a variety of parameters. The following are the basic parameters you’ll need for this tutorial:

  • data. A table containing elements that the list can iterate through to display in each row.
  • default. An image for the row background. Defines the hit area for the touch.
  • backgroundColor. Specify a table that contains R, G, B values. Example: {255, 255, 255}.
  • callback. A function that defines how to display the data in each row. Each element in the data table will be used in place of the argument (“item”) assigned to the callback function.

More about List View and parameters.

How to Use the List View

The List View is part of the Table View library. To use it, place a copy the tableView.lua file in the same directory as your main.lua file, then import the Table View classes in your code:

[cc lang=”lua” lines=”-1″]
tableView = require(“tableView”)
[/cc]

Now call the List View method:

[cc lang=”lua” lines=”-1″]
local myList = tableView.newList{ }
[/cc]

A simple table for a simple list

A simple table like this can be used to create a simple List View:

[cc lang=”lua” lines=”-1″]
local data = {
“Hot Coffee”,
“Iced Coffee”,
“Espresso”,
“Cappuccino”,
“Latte”,
“Americano”
}
[/cc]

Nice, but it’s not going to win you any awards. It’s time to learn about building multi-dimensional tables and using them for your data.


Set up a table with multiple entries in each row

The “callback” parameter is your best friend when you want to display something more complex than a single line of text in each row.

To display more than a single line of text, set up your data table to store multiple things in each row (i.e. setup a multi-dimensional table.)

[cc lang=”lua” lines=”-1″]
–setup the table
local data = {}

–setup each row as a new table, then add title, subtitle, and image
data[1] = {}
data[1].title = “Hot Coffee”
data[1].subtitle = “Grounds brewed in hot water”
data[1].image = “coffee1.png”

data[2] = {}
data[2].title = “Iced Coffee”
data[2].subtitle = “Chilled coffee with ice”
data[2].image = “coffee2.png”

data[3] = {}
data[3].title = “Espresso”
data[3].subtitle = “Concentrated by forcing hot water”
data[3].image = “coffee3.png”

data[4] = {}
data[4].title = “Cappuccino”
data[4].subtitle = “Espresso with frothy milk”
data[4].image = “coffee4.png”

data[5] = {}
data[5].title = “Latte”
data[5].subtitle = “More milk and less froth”
data[5].image = “coffee5.png”

data[6] = {}
data[6].title = “Americano”
data[6].subtitle = “Espresso with hot water”
data[6].image = “coffee6.png”
[/cc]

Of course, when you have lots more stored data to play with, you’ll want to setup your data table in a more automated fashion using a for loop.

Pass the data and setup the row display group

Now pass your data table as a parameter when setting up your List View. Also, specify the default background image for the rows:

[cc lang=”lua” lines=”-1″]
local myList = tableView.newList{
data=data,
default=”listItemBg.png”
}
[/cc]

Now let’s tell the list how to display the data in each row by specifying the callback function:

[cc lang=”lua” lines=”-1″]
local myList = tableView.newList{
data=data,
default=”listItemBg.png”,
callback = function( row )
end
}
[/cc]

Now create a display group in your callback function and return it as the result of the function. Each row will have this group and we’ll be putting everything for each row into this group:

[cc lang=”lua” lines=”-1″]
local myList = tableView.newList{
data=data,
default=”listItemBg.png”,
callback = function( row )
local g = display.newGroup()
return g
end
}
[/cc]

Let’s add a backgroundColor parameter, so we don’t end up with black text on a black background:

[cc lang=”lua” lines=”-1″]
local myList = tableView.newList{
data=data,
default=”listItemBg.png”,
backgroundColor={255,2552,255},
callback = function( row )
local g = display.newGroup()
return g
end
}
[/cc]

Here’s your list view! We haven’t told it which pieces of data to use in the rows, so the rows area all blank.

Pull the data into each row

The row argument of the callback function is important. The tableView.lua library passes each row of your data table as the row parameter to your callback function.

Now let’s add the text and images and insert them into the group using g:insert():

[cc lang=”lua” lines=”-1″]
local myList = tableView.newList{
data=data,
default=”listItemBg.png”,
backgroundColor={255,2552,255},
callback = function( row )
local g = display.newGroup()

local img = display.newImage(row.image)
g:insert(img)

local title = display.newText( row.title, 0, 0, native.systemFontBold, 14 )
title:setTextColor(0,0,0)
g:insert(title)

local subtitle = display.newText( row.subtitle, 0, 0, native.systemFont, 12 )
subtitle:setTextColor(80,80,80)
g:insert(subtitle)

return g
end
}
[/cc]

Final positioning

The text and images appear in each row now, but they need to be properly positioned using their x and y values:

[cc lang=”lua” lines=”-1″]
local myList = tableView.newList{
data=data,
default=”listItemBg.png”,
backgroundColor={255,2552,255},
callback = function( row )
local g = display.newGroup()

local img = display.newImage(row.image)
g:insert(img)
img.x = math.floor(img.width*0.5 + 6)
img.y = math.floor(img.height*0.5)

local title = display.newText( row.title, 0, 0, native.systemFontBold, 14 )
title:setTextColor(0,0,0)
g:insert(title)
title.x = title.width*0.5 + img.width + 6
title.y = 30

local subtitle = display.newText( row.subtitle, 0, 0, native.systemFont, 12 )
subtitle:setTextColor(80,80,80)
g:insert(subtitle)
subtitle.x = subtitle.width*0.5 + img.width + 6
subtitle.y = title.y + title.height + 6

return g
end
}
[/cc]

And that’s it! Now you’ve got text and images in your list view.

A note on the placement using x and y: If you notice that either your text or images appear blurry, this may be because the x and y values are not whole numbers. This could happen if you’re using a fraction of the width and height or some other property of the text or image to set the x and y. These need to be rounded off to whole numbers using math.floor() or math.ceil(). You’ll notice that in the code above for the images. In the example above, images and text are moved horizontally by half of their widths to get them to align up on the left.

Kicking it up a notch

Let’s make a simple addition: a background image.

Simply add an image to your code before the list to put it in the background. Then comment out the backgroundColor and change the text color to something lighter. Finally, swap out the default image for an image with a white pointer.

[cc lang=”lua” lines=”-1″]
–Add a background
local background = display.newImage(“coffeeBg.png”)

local myList = tableView.newList{
data=data,
default=listItemBg_white.png,
–backgroundColor={255,2552,255},
callback = function( row )
local g = display.newGroup()

local img = display.newImage(row.image)
g:insert(img)
img.x = math.floor(img.width*0.5 + 6)
img.y = math.floor(img.height*0.5)

local title = display.newText( row.title, 0, 0, native.systemFontBold, 14 )
title:setTextColor(255, 255, 255)
g:insert(title)
title.x = title.width*0.5 + img.width + 6
title.y = 30

local subtitle = display.newText( row.subtitle, 0, 0, native.systemFont, 12 )
subtitle:setTextColor(180,180,180)
g:insert(subtitle)
subtitle.x = subtitle.width*0.5 + img.width + 6
subtitle.y = title.y + title.height + 6
return g
end
}
[/cc]

Here’s the final result!

Adding display logic and custom behaviors to each row

Using if-then statements in the callback function and adding other ui display objects, like ui.newButton{}, you can really get creative and allow the user to perform all sorts of complex operations.

I’ll cover that in my next blog post. Stay tuned!

Download

Download sample files for this tutorial.

Share on Facebook0Share on Google+0Tweet about this on TwitterShare on LinkedIn0
carlos

This entry has 65 replies

  1. David Knell says:

    Great tutorial! Really looking forward to the next one!

  2. Yes, that is great. Next!

  3. miro says:

    Great tutorial!

  4. Thanks for this great tutorial.
    How can we migrate this style to work just within a defined rectangle as opposed to this full screen example. On the iPad, its less effective full screen than if we can scroll within a block area.

  5. Flavio says:

    I am still not understanding why after months of work of my TableView.lua and gui.lua never were published, neither shared, neither posted in the hole CORONA website, blog and forum when I sent it several times to Ansca Staff even with direct emails. Finally I shared a website link to my code about it, so there was people who download it since May 2010.

    I am really disappointed that part of my code that could be used here, never mention any relation to my previous code.

    For people interested to find that previous and old code, here is the link: http://www.vlsarg.tk/

    BTW, this explanation is great and probably the code too.

    Congrats to the person how won the possibility to share it here.

  6. Gilbert says:

    I just updated the zip file for this tutorial. There have been a lot of questions about using the List View on the iPad. If you run this demo in the simulator on the iPad you’ll notice that it grows to fill the screen. However, it would be much better to adjust the layout. This is easy to do in Corona! Download the new zip file and you’ll see how.

    I added a few lines to the code in the main.lua file to do the layout adjustments. Before running it in the simulator or building for iPad, open config.lua and build.settings and change the scaling and orientation settings. (Comment out the lines in config.lua and uncomment the lines in build.settings.) And that’s it!

    Here’s a screenshot.

  7. miro says:

    In the code above should

    default=listItemBg.png,

    be

    default=”listItemBg.png”

  8. Gilbert says:

    Thanks for catching that error @miro! I corrected the blog post.

  9. Arms says:

    Is there a way to add a stationary image at the top of the list? so i.e. a 30px in height logo for the app, then the list view appears underneath that and is scrollable while the icon doesn’t move.

  10. paul magnan says:

    Awesome! I am impressed.

  11. paul magnan says:

    very impressive, can’t wait for the next.

  12. Bedhouin says:

    Is there a way to encapsulate the list vertically allowing for draw objects either at the top or bottom for buttons.

    If the list was a in sub menu how would you cancel out of it and go back to the previous screen without making a selction?

  13. Bedhouin says:

    aaah Found the List View demo in the Samples folder which does have a marquee title bar at the top with navigation. Good stuff. You should update this blog entry to reflect this.

  14. Dan says:

    I’m trying to clip the scrolling list to an arbitrary window. I created a background with a transparent portion representing the window through which the scrolling item can be viewed. If 0,0 is the top left corner of the screen, the y coordinate of the top of the transparent portion is 100 and the y coordinate of the bottom of the transparent portion is 380.

    How do I setup this example to do what it already does, but do it within the confines of my window?

  15. Best tutorial! Really looking forward to the next one!

  16. Ashlee says:

    I am trying to set this up in a rectangle too. I have tried changing what I thought were the H and W properties but with no luck. Is there a way to make it so its not taking up the whole iphone screen??

  17. Imran says:

    There a many ways to encapsulate the list vertically allowing for draw objects either at the top or bottom for buttons. New code should be written to make it happen.

  18. Andre says:

    Hi, how to open a new file when tapped? Or a more complex screen? with more text, images, etc.

    Any suggestions?

    thanks!!!

  19. Benjamin says:

    Does anyone have an insight in how to load this data into the tables with a for loop from an sqllite database?

    I have a database imported a database much like the sqllite samples demos
    but when I try to load the data with a for loop but it does not work. The print works but the content isn’t loaded into the table it throws an error,

    Does anyone have an samples they could provide on how to get database content into a table format?

    Thanks

    local i = 1
    for ID,Name,SmallImg in db:urows(“SELECT * FROM products”) do
    print(ID,Name,SmallImg)

    data[i] = {}
    data[i].id = ID
    data[i].name = Name
    i = i + 1

    end

  20. Carlos Icaza says:

    @benjamin

    it would be better if you ask in our forum instead of the blog post.

    developer.anscamobile.com/forum

  21. Benjamin says:

    @carlos

    I would really like to post on the forum but for some reason, when I am logged in it says,

    “You are not allowed to post new content in the forum”

    I am not sure why. Any ideas?

  22. carlos icaza says:

    You are unverified. An email was sent to you to verify your account. You must respond to the verification email in order to post in our forum.

    C

  23. Rooster says:

    Any API to parse rss/atom feeds into a list?

  24. Alberto says:

    Hi, Gilbert!
    I am a newbie so excuse me for this question: Is it possible that the list is only the half of the screen?

    Thanks in advance,

    Alberto

  25. Oleg Kokorin says:

    To everyone trying to have the list occupy only half of the screen: the easiest solution is to overwrite area over the list and below its bottom boundary with something. For example, if you have an app that you don’t want to scale up to the entire screen on iPad, use black rectangles over and below the list. I also had to slightly hack the event handler so that touch and release are ignored when outside of desired area.
    This is not a pretty solution, but it worked like a charm.

  26. karl says:

    here is a hard one…

    what if you have big list with images and want to do a lazy load?

    any way to do that in corona?

  27. @karl

    not hard at all and it has been implemented by virtualization by Gilbert. Grab the latest code in our code exchange.

    C.

  28. ZaidiSoft says:

    Very educative and simple-to-follow tutorial. I just found out about Corona SDK and I am lovin’ it already. I am trying to get all the basics before I start using it.

    Great work and looking forward to more educational tutorial like this one.

    Thanks

  29. ZaidiSoft says:

    Hello Carlos,

    Do have the link to the code you are referring to above? I have the same question as Karl.

  30. Edward M says:

    How do you remove some rows, making the list shorter (4 or 5 items)?

  31. Edward M says:

    Oh, I figured it out. Adding display logic and custom behaviors to each row seems like the next step? Is that tutorial out already? I can’t find it.

  32. Noobie says:

    The table view does not show up on the mytouch or droid and i dont have and iphone or ipad simulator in my corona for some reason… When i typed in the whole code and load the file in my droid simulator the screen is just black… PLEASE HELP!

  33. Joe says:

    I’m just starting to learn Lua, and I have a very simply question: in this list, the items are repeated twice, how can I display each item only once?

  34. sam says:

    hi thanks for tutorial .i’m using list view in my app .after menu screen i’m loading listview it’s working fine but problem is that ‘how can i go back to menu page from listview ‘can any one tell me as i’m new in corona thanks in advance

  35. Kevin says:

    Is it possible to reorder a listview? I would like to use an ‘OnPress’ callback rather than an ‘OnRelease’ callback, which would start a timer, then onRelease you could check if that timer was over a certain figure (a long press).

    From this it would be nice if you could drag and drop a listview item to reorder it

    Is this possible?

  36. Chris says:

    Hi All,

    Is there a way to force a refresh/reload of the data on a tableView. I’m making an app where you tap a button to show a different group, in that new group you add a record to a sqlite database table and get returned to the original group with the tableView in. I need to reload this tableView to show the new value from the database.

    Thanks in advance for any help!

  37. Jeff says:

    Hello, I’m currently making an app at my school and I’m using this code as a basis but I want to know how to fill in the detail screen for each tab individually and be able to format the text so it doesn’t go off screen.

    Ex: My app is a list of the clubs at our school so if you were to click on Breakdance Club it would give you a description of the Breakdancing Club and what not.

    Thanks to anyone if they can help. :3

    • Michael says:

      Hiya did you find out how to do this, I’m wanting to do the same thing.

  38. Gilbert, this is just what I needed. Thanks for taking the time to write this out so clearly.

  39. Scott says:

    How an i modify it so once you click on something on the list the page that is oaded displays the title and bellow that data[i].description? What lines would have to be added?
    I am fairly new to corona so please tell me as simply as possible…

  40. Scott says:

    I figured out the last one now the only thing I cant do is multiline text in the description text. Can anyone explane how to do it, or is there a tutorial?

    • Michael says:

      Hi Scott,

      How do you change the descriptions for the items? Have you worked out the multi-line yet? I’m trying to do the same thing.

      – M –

  41. waseem sarwar says:

    Very useful help.

  42. Andre Borges says:

    Hi Gilbert!

    Really liked your example. Thanks for post it. I have a doubt and would like your help. How would i insert a table view inside another? Let’s say that instead displaying “You tapped XYX” i would like another table view to be displayed. Do you have any example that tell us how to do it?

    Thanks,
    Andre

  43. Mike says:

    Is it possible to specify width, height and position? If it is please post code showing an example.

  44. Ahmed says:

    How can i make the vertical scrolling as the code doesnt support it ??

  45. Ahmed says:

    Sry i mean Horizontal

  46. Suhada says:

    @Carlos:
    You said at the end of the post
    I’ll cover that in my next blog post. Stay tuned!

    I couldn’t find that next post.
    Did you ever do it as I’d love to see how you do buttons in a list view.

  47. carlos says:

    great tutorial! i do a have a question tho.when you press the ” hot coffee” button, it trows you to another page saying “you pressed hot coffee button”, how do i add the info that i want to display underneath it? or how do i add a photo underneath it as well.

    many thanks!

    Carlos

  48. Carlos says:

    Let me get if I got this thing straight, tabes are like div wrapper ( CSS ), list are like the others divs containing the “coffee etc ” right? How do i manipulate what’s inside the list or multi dimensional tables once I click inside them?

  49. Gul says:

    I’ve been trying to make each of the tables click through to a new page but seem to be getting lost.

    Any help would be appreciated thanks.

  50. Ben says:

    How would i go about putting a header image that would scroll with the list?

    Thanks for the great tut!

  51. Hansel says:

    is it possible to change screens when hitting a selection on the list? Ive been trying to do this for serveral days but havent gotten anywhere. Please help

  52. Greg says:

    Is there a way to put a widget button inside a TableView row? To emulate the iPhone preferences screen? Have created this forum post for a response if this assists:

    http://developer.coronalabs.com/forum/2012/07/29/best-approach-replicate-iphone-scrollable-list-view-textbuttons-etc-both-android

  53. jos says:

    how to make each of the tables click through to a new page

  54. Facada says:

    Hi,

    Has anyone did this with remote images?

    Thanks

    • Vudao says:

      The same problem on this demo working with remote image. Anyone help?

  55. Mazen Salih says:

    Hi,
    How can I get that code to work on a “menu.lua” file?

  56. Michael says:

    Anyone found out yet how to have a description on the next page for each of the list items?

  57. Neel says:

    How can we store the value in list value from database..???

    Suppose i want to store the data in list view from particular table..?? how can i do that
    i want to display the row name from the table
    Please Give me the urgent Replies
    I am new to corona. Thanks

  58. Maria says:

    Hello good day can help me I need to store images in sqlite and return them to the mobile device

  59. sangu says:

    in my code its showing tableView is not available.
    does it support in pro-coron sdk version or can i use it in trial sdk also?
    my code is as below:-

    local tableView = require(“tableView”)
    local data = {}
    local msg = {“hello sangam thanks”, “you are most welcome”,”are you game developer?”,”cross platform for mobile”,”i m software deveoper”}

    for i = 1, #msg do
    data[i].messsage = msg[i]
    data[i].btn = “Delete”
    data[i].image = “next_arrow.png”
    table.insert(data, data[i])
    end

    local myList = tableView.newList{
    data = data
    }

Leave a reply

You may use these HTML tags and attributes: <a href="" title="" rel=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url="">