B4A Library [Class] TableView - Supports tables of any size

An improved version of this class is available here: http://www.b4x.com/forum/additional...icial-updates/30649-class-flexible-table.html


The Table class allows you to show tables of any sizes. The views (labels) are reused to avoid creating many views.

With the help of StringUtils the table can be loaded and saved to a CSV file. It shouldn't be difficult to show SQL tables using DBUtils.ExecuteMemoryTable.

SS-2012-07-04_10.38.01.png


Follow the attached example to see how the class is used. To add it to your own project you need to add the class module to your project and add a reference to StringUtils library.

RemoveRow code is available here: http://www.b4x.com/forum/showpost.php?p=146795&postcount=147

V1.10 uploaded. New method: SetColumnsWidths. Allows you to manually set the width of each column
V1.11 uploaded. Fixes a bug with grey stripes appearing.
 

Attachments

  • Table.zip
    14.9 KB · Views: 7,945
Last edited:

jeffnooch

Member
Licensed User
Longtime User
Yes, the new code adds the table (it's container panel) onto the object you define in AddToActivity.
Look at the attached example program, in AddToActivity replace Activity by your full screen Panel.

Best regards

Klaus...i was currently using the full page panel and had that on the addtoactivity already...
the good news is i didn't have to make any changes to my code....
the better news is the change you made to the class is working exactly as i intended...
appreciate your help...
 

jeffnooch

Member
Licensed User
Longtime User
Klaus...
One more question:
Is there a way to hide a table (or essentially the panel that is holding the table)...so if i have 4 tables but wanted to click a button or something to hide one of the tables would that be possible? i know i could hide my full screen panel...but i'm curious if there is a way to hide just one of the table panels...
Thanks again...
 

Bryan

Member
Licensed User
Longtime User
I've been working with this class for a few days now. I wasn't using the class at the start and was just using all functions in the main activity as just a modified scrollview. That worked very well. I am having an issue with the class adaption of the scrollview table.
I am trying to get "jumptorow" to work after I add a row to the table and it does not go to the last row in the table. Instead it scrolls down to the second last row about midway between the top and bottom of the row. I remembered an issue with the this in a table created without using the class that DoEvents had to be inserted between the AddRow and the scrolling to the bottom of the table function.It does not seem to make any difference doing that. Below is not the complete code just parts of it that may be important.

I added to the class

B4X:
Public Sub Size As Int    
Return Data.Size-1
End Sub

B4X:
In the main activity I have

Sub Globals
Dim TableMod As Table
Dim Footer As Panel
Dim LogButton As Button
Dim FontSize As Float
Dim string1,string2,string3,string4 AS String


Sub Activity_Create(FirstTime As Boolean

TableMod.Initialize(Me, "TableMod", 4)
TableMod.RowHeight = 30Dip
TableMod.AddToActivity(Activity, 5%x, 0%y, 90%x, 90%y)   
TableMod.SetHeader(Array As String("one", "two", "three", "four"))

Footer.Initialize(0)
LogButton.Initialize("OK")
LogButton.Text = "LOG"
LogButton.Typeface = Typeface.DEFAULT_BOLD
Footer.Color = Colors.DarkGray
Activity.AddView(Footer, 5%x, 90%y, 90%x, 10%y)
Footer.AddView(LogButton,33%x,2%y,25%x,8%y)
TableMod.LoadTableFromCSV(File.DirRootExternal,"1.csv", True)
End Sub

Sub OK_click
TableMod.AddRow(Array As String(string1,string2,string3,string4)
TableMod.JumpToRow(Tablemod.Size-1)
End Sub

Another issue I am having is once the application I'm writing that is using the table class installed on another device what would be a good way to create the CSV file if it is not on the device with the application or it gets removed by accident. If the file is missing then the application crashes. I think it would be good to check if the file exists then if not create it. But it would seems it needs the header and least one row of data to work.

Thanks
Bryan

I fixed it by doing

TableMod.JumpToRow(TableMod.Size)
DoEvents
TableMod.JumpToRow(TableMod.Size)

I also figured out how to create a csv file if one does not exist.
 
Last edited:

peacemaker

Expert
Licensed User
Longtime User
BTW, if interesting, I'm using the adjustment of the RowHeight:
B4X:
'Clears the previous table and loads the CSV file to the table.
'You should first add the Table to the activity before calling this method.
Public Sub LoadTableFromCSV(Dir As String, Filename As String, HeadersExist As Boolean)
   
   Dim List1 As List
   Dim h() As String
   If HeadersExist Then
      Dim headers As List
      List1 = StringUtils1.LoadCSV2(Dir, Filename, ";", headers)
      Dim h(headers.Size) As String
      For i = 0 To headers.Size - 1
         h(i) = headers.Get(i)
      Next
   Else
      List1 = StringUtils1.LoadCSV(Dir, Filename, ";")
      Dim firstRow() As String
      firstRow = List1.Get(0)
      Dim h(firstRow.Length)
      For i = 0 To firstRow.Length - 1
         h(i) = "Col" & (i + 1)
      Next
   End If
   innerClearAll(h.Length)
   ColumnWidth = SV.Width / NumberOfColumns
   SetHeader(h)
   '-----------------------vlad----------------
   MaxCellText = -1
   For i = 0 To List1.Size - 1   'calc row height
      Dim ss() As String
      ss = List1.Get(i)
      If MaxCellText.Length < ss(1).Length Then
         MaxCellText = ss(1)
      End If
      If (i Mod 300) = 0 Then DoEvents
   Next
   
   Dim LLL As Label
   LLL.Initialize("")
   SV.Panel.AddView(LLL,0,0, Header.GetView(0).Width, RowHeight)

   LLL.Text = MaxCellText
   AdjustHeight(LLL)
   RowHeight = LLL.Height
   LLL.RemoveView
   '-----------------end_vlad-----------------
   
   
   For i = 0 To List1.Size - 1
      Dim row() As String
      row = List1.Get(i)
      AddRow(row)
      If (i Mod 200) = 0 Then DoEvents
   Next
End Sub
 
Last edited:

Espinosa4

Active Member
Licensed User
Longtime User
Hi guys,

How can I to change the cell fontsize and colours, please? I try to use Table1.Fontsize and nothing change around the cells.

Cheers,
Espinosa
 

Espinosa4

Active Member
Licensed User
Longtime User
Change the font size before you fill the table with Table1.Fontsize = xx and add Table1.ClearAll just after it, something like this :
B4X:
Table1.Initialize(Me, "Table1", 4)
Table1.FontSize = 20
Table1.ClearAll
Best regards.

Thank you very very much Klaus!! Now it works perfectly!!
Cheers.
 

EMO

Member
Licensed User
Longtime User
I like it. It's posible to add diferents alignment for each column?
Im try, but i cant.
Sorry by mi english, Im from Spain.
Thanks
:sign0085:
 

SandroB4A

Member
Licensed User
Longtime User
First of all I wish to thanks Erel&Klaus for this wonderfull class, now I can visualize data with professional layout, I have also added a footer with sum, average..etc, funny but I have two question:

1) Is it possible to make multiple selection of rows? I'd like to select on/off the rows by clicking on a cell.
I've commented Sub SelectRow to avoid removing the color of previously selected row.

B4X:
Private Sub SelectRow(rc As RowCol)
   'Dim prev As Int
   'prev = SelectedRow
   'SelectedRow = rc.Row
   ''remove the color of previously selected row
   'If prev > -1 Then
      'If visibleRows.ContainsKey(prev) Then
         'HideRow(prev)
         'ShowRow(prev)
      'End If
   'End If
   
   SelectedRow = rc.Row
   SelectedCol = rc.col
   
'   For col = 0 To NumberOfColumns - 1
      If visibleRows.ContainsKey(SelectedRow) Then
         HideRow(SelectedRow)
         ShowRow(SelectedRow)
      End If
'   Next
End Sub

Then I've tried catching drawable type of cells background without success. Something like:


B4X:
Private Sub Cell_Click
   Dim rc As RowCol
   Dim l As Label
   l = Sender
   rc = l.Tag
   SelectRow(rc)

   SwitchRowCol         '--------New Sub

   If SubExists(Callback, Event & "_CellClick") Then
      CallSub3(Callback, Event & "_CellClick", rc.Col, rc.row)
   End If
End Sub

Private Sub SwitchRowCol
Dim lbls() As Label
For i=0 To lbls.Length-1
   If lbls(i).Background=SelectedDrawable(i) Then
      lbls(i).Background=Drawable1(i)
   Else
      lbls(i).Background=SelectedDrawable(i)
   End If
Next
End Sub

If I can get selected rows then I could copy or delete them quickly, a big improvement for my app.

2) in the SelectRow Sub code wich is the reason of the for statement?, commenting it seem to work fine as well.

Thanks in advance for any help you can give me.
 

klaus

Expert
Licensed User
Longtime User
It is possible.
I had done this with a ScrollView here using a List to memorize the selected rows.
You could take the principle from the example above to modify the SelectRow routine.

You are right, the For/Next loop in the SelectRow routine is not necessary.

Best regards.
 
Last edited:

melamoud

Active Member
Licensed User
Longtime User
version of table class with the features you wanted

hi guys,

there is a version of this class with multi select, and with other nice features like footer and sorting by column etc
see http://www.b4x.com/forum/additional...ss-tableview-supports-tables-any-size-22.html

here is a minor update to that version with the following fixes
'Version 1.19
' fix last column (if no empty space, its very hard to choose it)
' fix size of sorting icons on columns

' whats new 1.18
' bug fix, table can now start on left <> 0 without weird horizontal scroll issues - thanks klaus
' add method addToView - which is the same as add2Activity - but a better naming - you can still use addToActivity - depricated like method.
 

Attachments

  • Table.zip
    8.3 KB · Views: 340

andre.astafieff

Member
Licensed User
Longtime User
I am not able to use the class. Quall would be the problem in the code below?

B4X:
Sub Globals

   Dim BrancoDados As MYSQL
    Dim CarregaTabela As List
    Dim hsv As HorizontalScrollView    
    Dim svRows As ScrollView
   
   
   Dim Table1 As Table 
End Sub

B4X:
Sub Activity_Create(FirstTime As Boolean)

    BrancoDados.setDatabase(Main.IpServer,"ondebebi","bebi","123456")

    CarregaTabela=BrancoDados.Query("select * from bebedeira where mail_user ='" & Main.UserGlobal & "'")
    
    If CarregaTabela.IsInitialized=False Then
        Msgbox("Sem registros...","ERRO!")
        Return
    End If
    

   Table1.Initialize(Me, "Table1", 11)
   Table1.AddToActivity(Activity, 0, 0dip, 100%x, 50%y)   

    Table1.SetHeader(Array As String("id", "email", "Cerveja Garrafa", "Cerveja lata", "Destilado", "Água", "Refrigerante", "Latitude", "Longitude", "Hora Inicio", "Hora Término"))

    For i=1 To CarregaTabela.Size-1
   Log(CarregaTabela.Get(i))
      Table1.AddRow(Array As String(CarregaTabela.Get(i)))
   Next
   
End Sub

returns "Wrong number of values."
 
Top