B4A Library Grid/Table and ListView Library

This library allows to create easely grids/tables and
from version 2.50
list views too!

The original post has been moved

Version 2.50 beta
- Added support for multiline rows

Version 2.51 beta
- Bug fixes

Version 2.52 beta
- Added Typeface support for rows and hedaer

Version 2.53
- Added SingleLine property for columns

sample code and usage hints can be found here

Version 2.55
- Added object b4aActivityContext

Version 2.56
- Added and modified event hendlers

Version 2.57
- Added Columns Builders

Version 2.58
- Bug fixes

Version 2.59
- Added RowHeight for each column
- Added HeaderHeight for each column

Version 2.60
- Added TouchX() and TouchY()
- Added FirstVisiblePosition() and LastVisiblePosition()

Version 2.65
- Added Button Columns

Version 2.67
- Added CellProps event
- Removed PropSetColor / PropSetTextColor

Version 2.71
- Added OnSelectAllow event
- Added selection on row background

Version 2.73
- Added OnRowProps event

Version 2.76
- Fixed dubug log bug

If you like my grid.
You can support the development.



  • xnGridSample200beta.zip
    3.6 KB · Views: 2,071
  • xnGrid2xx_1.png
    77.2 KB · Views: 5,148
  • xnObjects267.zip
    75.7 KB · Views: 803
  • xnObjects272.zip
    87.2 KB · Views: 602
  • xnObjects273.zip
    87.5 KB · Views: 698
  • xnObjects276.zip
    87.2 KB · Views: 1,450
Last edited:


Well-Known Member
Licensed User
Longtime User
Can I change the colors of the header?

--- Jem


Active Member
Licensed User
Longtime User
already planned

I'm finishing multiselection
After that i've planned the layout improvements
Give me a few days
Last edited:


Licensed User
Longtime User
I know this opens a potential for never ending possibilities, but could you add text sizing for header and rows, text positioning for columns and default row colors (black and grey is set now).

Great job so far!


Licensed User
Longtime User
The grid is, in many cases, used to display records from a sql table. From what I can determine, the xnTable is a memory map of string "fields". One may declare many fields with xnTable.Initialize( Array As String ("locId" , "region" , "city" , "other" ) ).

To populate these fields from a sql table:

Dim r As Int
Dim SQL2 as SQL
Dim cur As Cursor

cur = SQL2.ExecQuery( "SELECT * FROM Location WHERE region = 'ON'")

tt.Initialize( Array As String ("locId" , "region" , "city" , "other" ) )

If cur.RowCount > 0 Then
For r = 0 To cur.RowCount -1
cur.Position = r
tt.Append ( Array As String ( cur.GetInt("locId") , cur.GetString("region") , cur.GetString("city") , "o=" & r ) )
End If

Now, create the grid object and columns...


Dim c0 As xnGridCol
Dim c1 As xnGridCol

c0.Initialize ( "ID" , "locId" , 140dip )
gg.Columns.Add ( c0 )
c1.Initialize ( "State" , "region" , 120dip )
gg.Columns.Add ( c1 )

Add a view and create the grid...

Activity.AddView ( gg ,10dip , 10dip , 100%x , 100%y )
gg.GridCreate ( tt )

The grid row select event determines the row selected by user, and can get / set the values for any column added above. GREAT! It seems that only columns "added" can be get/set.

However, since this lib is not a DBGrid, the developer must take the appropriate actions to Update the source table with applicable edits or deletions - usually when "Finished" using the grid. I now see how difficult it would be to impliment a full DBGrid without a DataSet object to help determine the table structure. THIS lib is the next best thing...

In the example above, I would like to use two (or more) "hidden" columns - (can update the contents but not display in the grid). These columns would be: PKey_Col and Edit_Col. When a row/col is modified, the Edit col is set to 1 (or 2 for delete). Example: c0.Initialize ( "ID" , "locId" , 140dip, False ) - updatable but not visible in grid. An updatable Tag object for each row could also accomplish the same thing, using a Type.

When finished with the grid:
For i = 0 To gg.RowCount - 1
If tt.GetValue(i, EditCol) = "1" then
Update the SQL table using the Primary key of PKey_Col
End If

If tt.GetValue(i, EditCol) = "2" then
DELETE the table record using the Primary key of PKey_Col
End If

Can you also explain what the meaning and use is for each property of each object (ie. tt.GetValueSafe, gg.ba, gg.RowStandard, etc)?

Your effort to date is remarkable. It has and shall significantly reduce the amount of code and complexity it takes to implement a grid.

Moving forward, with guidance, suggestions and help from others, this project will result in what many have been wanting for some time without the positive contribution in what they are asking for (taking for granted (and spoiled by) what is in Delphi and other dev platforms). It seems that Android itself has not evolved to natively embrace the concept of Database Grids (ListViews are much easier to deal with). The core of my apps use databases, tables, records and fields - everything else is merely GUI pretty presentation. I may be missing something (or everything), but business does not seem to have a large following in Android due to the "fun and games" aspect of its' percieved use.

We, who attempt to devlope industrial business apps hope to change that perception. Currently, the solution for tranfering SQLlite database records is to create a CSV file. Sure we can, but is there not a more modern way (encrypted, compact, structured method) that will easily import into MSSQL - Oracle and others?

All help greatly welcome.



Active Member
Licensed User
Longtime User

xnTable is a memory structure to store the data to be displayed in one grid.
But you can also have columns in an xnTable that are not displayed in any xnGrid or ... having more xnGrids displaying data of the same xnTable.
In the example i've posted the "other" column is not present in the grid.
So if "gg" is a grid, "tt" is the underlying table and if the column "other" is the 4th column of the table you can get this value with
tt.GetValue ( gg.RowSelected , 3 )

Here about the xnTable object
getRows() number of rows = records
getCols() number of columns = fields

GetValue ( int Row , int Col ) the value of a cell
GetValueSafe ( int Row , int Col ) ... if row and col are valid indexes
in the first case an index out of bounds raises an exception in the second
you'll simply get a null result

SetValue ( int Row , int Col , String Value )
SetValueSafe ( int Row , int Col , String Value )
the setter with the same logic as the previous two

Delete ( int Row ) used to delete the specified row

Insert ( String [] Values , int Row )
InsertFromMap ( Map map , int Row )
used to insert a row in the specified position
you can pass an array of strigns or a map
i'm working to pass a record

Append ( String [] Values )
AppendFromMap ( Map map )
use to append a row ...

i'm also planning to extend the class to have typed columns
and some other features i need to work with database but not only databases!

now i'm fixing the gravity property and finishing the xnGrid object
did i forget something?


Licensed User
Longtime User
It gets better by the minute!

I shall try it out and get back to you


Licensed User
Longtime User
greet job stefanobusetto, i like it.

can you say me, how can i change the color of selected-row?
Or imposible at the moment.


Licensed User
Longtime User
Hello stefanobusetto,

i thank you for your effort.

Can i add a Row at Runtime?
Please look my code below:

Sub Globals
   'These global variables will be redeclared each time the activity is created.
   'These variables can only be accessed from this module.
Dim gg As xnGrid
Dim tt As xnTable
End Sub

Sub Activity_Create(FirstTime As Boolean)
      tt.Initialize ( Array As String ( "Anz" , "PLU" , "Name" , "Preis" ) )
      For r = 0 To 1
      tt.Append ( Array As String ( "a" & r , "b" & r , "c" & r , "12.50"  ) )

''Here I can add a new row without any problems
      tt.Insert ( Array As String ( "3" , "125"  , "Cola mit Eis 0,3" , "2.50"  ),0)
      tt.Insert ( Array As String ( "2" , "122"  , "Cola mit Fanta 0,3" , "2.50"  ),0)
'      gg.HeaderHeight=50
'      gg.RowEvenColor = Colors.Green
'      gg.RowOddColor = Colors.Red 
'      gg.Color = colors.DarkGray 
'      gg.SelectedEvenColor = Colors.Yellow 
      Dim c0 As xnGridCol
      Dim c1 As xnGridCol
      Dim c2 As xnGridCol
      Dim c3 As xnGridCol
      gg.RowHeight = 50dip
      c0.Initialize ( "Anz." , "Anz" , 50dip )
      gg.Columns.Add ( c0 )

      c1.Initialize ( "PLU." , "PLU" , 50dip )
      gg.Columns.Add ( c1 )

      c2.Initialize ( "Speisename" , "Name" , 150dip )
      gg.Columns.Add ( c2 )
      c3.Initialize ( "€" , "Preis", 70dip)
      gg.Columns.Add ( c3 )

      Activity.AddView ( gg , 0dip , 130dip , 400dip , 300dip )
      gg.GridCreate ( tt ) 
End Sub

'Here I would like to add a new row, but not happens
Sub Button1_Click
   tt.Insert ( Array As String ( "2" , "122"  , "Eistee 0,3" , "2.50"  ),0)
End Sub


Active Member
Licensed User
Longtime User
Not yet.
I've planned to add something like 'refresh" to the whole grid.
Since structure of the grid is a table layout filled with table rows ( ans fields) i don't tink it is possible to insert or delete a table row.
I have to try.


Active Member
Licensed User
Longtime User
Great, but need much more features...


Thank you for this library!
I'm developing my own custom grid, completely in B4A, for an inhouse app.

Yours is a very good start, but it needs a lot more features, perhaps for v2 :):
  1. Radiobuttons, buttons, checkboxes, images, ...
  2. Multiline support for all fields: e.g. labels height is automatically changed according to the content.
  3. Some custom columntypes like 'color', 'progressbar', ...
  4. Column Formatting: decimal places, datetime formatting, ...
  5. Custom eventnames: the ability to provide the name of the event per column, so when a radiobutton is clicked, I get the event in my activity.
  6. Columns placed at a second line within the same row (tricky one).
  7. Column horizontal/vertical spanning (very tricky one).
  8. Sorting by columnheader.
  9. Custom 'Tag' binding: by pressing a buttonfield, the ID (or other field of the record) should be placed in the 'Tag' property of that button for further handling.
  10. Many more :)
Most of the above things are working in my own grid, but I have no selection, multiselection, spanning or sorting yet ;).



Licensed User
Longtime User
Hello stefanobusetto,

It would be great if you can add this Future (add or delete a row at Runtime) in your library, and easy export table-content to an array or into a file (CSV/xml etc).



Active Member
Licensed User
Longtime User
Hi kaplanerkan,
Insert and delete are planned. If i find the way.
The export feature i dont know.