Android Tutorial Creating a table view based on ScrollView

Status
Not open for further replies.
A much improved version is available here.

You can use the code in this example to show data in tabular form.

table_1.png


The table is made of two main views. The header row is made of a panel with labels. The main cells component is made of a ScrollView with labels as the cells.

You can modify the code to change the table appearance.
Some of the settings can be changed in Sub Globals:
B4X:
    'Table settings
    HeaderColor = Colors.Gray
    NumberOfColumns = 4
    RowHeight = 30dip
    TableColor = Colors.White
    FontColor = Colors.Black
    HeaderFontColor = Colors.White
    FontSize = 14
Adding data to the table:
B4X:
    'add header
    SetHeader(Array As String("Col1", "Col2", "Col3", "Col4"))
    'add rows
    For i = 1 To 100
        AddRow(Array As String(i, "Some text", i * 2, "abc"))
    Next
    'set the value of a specific cell
    SetCell(0, 3, "New value")
    'get the value 
    Log("Cell (1, 2) value = " & GetCell(1, 2))
Table events:
B4X:
Sub Cell_Click
    Dim rc As RowCol
    Dim l As Label
    l = Sender
    rc = l.Tag
    activity.Title = "Cell clicked: (" & rc.Row & ", " & rc.Col & ")"
End Sub
Sub Header_Click
    Dim l As Label
    Dim col As Int
    l = Sender
    col = l.Tag
    Activity.Title = "Header clicked: " & col
End Sub
The code is not too complicated and you can further customize it as needed.
 

Attachments

  • TableExample.zip
    5.7 KB · Views: 6,681
  • TableExample1.1.zip
    12.2 KB · Views: 7,056

ajk

Active Member
Licensed User
Longtime User
I have changed

Dim l As Label
to
Dim l As EditText

Now I can edit table cells, but:
1-st press of cell sets focus on the field and call the keyboard to appear
2-nd press of cell call sub cell_click

Question:
how to avoid second click on the cell to rise cell_click?
 

jester_malcolm

New Member
Licensed User
Longtime User
Hi,

I added a simple function for myself to set the background color of a single cell, which works fine when populating the data in the grid.
To access the inside labels I use the GetView method of the scrollview panel.

I've noticed that after selecting a row (call of subs HideRow and ShowRow), the inner position of the labels gets rearranged so that my calculated position of the cell is not matching my desired access point anymore.

Why is this effect and how would you suggest to cope with it?
One assumption could be, that the function HideRow also deletes the position index of the view, when calling RemoveView?

best regards
Ray
 

GMan

Well-Known Member
Licensed User
Longtime User
I collect datas (by date) in this list (4 columns)

How can i make the background for the cells with same date looking in another color (maybe gray) then the other days ?
Gray (and as used white) would be enough - its only fo better visibility.

Example
30.05.2014 07:45 some datas (bg = white)
30.05.2014 09:31 some datas (bg = white)
30.05.2014 12:14 some datas (bg = white)
30.05.2014 18:12 some datas (bg = white)
31.05.2014 06:08 some datas (bg = gray)
31.05.2014 10:29 some datas (bg = gray)
31.05.2014 11:17 some datas (bg = gray)
01.06.2014 07:28 some datas (bg = white)
01.06.2014 09:11 some datas (bg = white)
...
etc.

The among of datasets varies from day to day.
 

GMan

Well-Known Member
Licensed User
Longtime User
Thx , thats not worth it.
it should only be a simple list and that is fine
 

ykucuk

Well-Known Member
Licensed User
Longtime User
Thanks for your example

i have a little problem with the created table.
When i start the layout and i load my table rows from my webservice then i get a error message at this point:

Sub GetView(Row As Int, Col As Int) As Label
Dim l As Label
ScrollView1.Initialize(100%x)
l = Table.GetView(Row * NumberOfColumns + Col)
Return l
End Sub

l (TextView): Layout not available, Text =
LastException java.lang.RuntimeException: Object schould first be initialized (View)

When i skip it and say yes on the tablet, then all information i want are listed in the table without errors.

Can you help me, what my problem ist at this point?
 

ykucuk

Well-Known Member
Licensed User
Longtime User
I cant sent my Project, but i can post my activity module with the Scrollview.

I deleted my server Adress on the module
 

Attachments

  • SC.zip
    2.2 KB · Views: 503

ykucuk

Well-Known Member
Licensed User
Longtime User
sorry my bad, i have saved it on Notepad++
i cant upload it, the file is too big
I post my Code here

B4X:
#Region  Activity Attributes
    #FullScreen: False
    #IncludeTitle: True
#End Region

Sub Process_Globals
    'These global variables will be declared once when the application starts.
    'These variables can be accessed from all modules.

End Sub

Sub Globals
    'These global variables will be redeclared each time the activity is created.
    'These variables can only be accessed from this module.
   
    Dim Parser As SaxParser
    Dim PD_ProductID, PD_CartonContent, PD_Name, PD_Unit, PD_Tax, PD_Barcode, PD_Price, PD_inStock As String
   
    'Table
    Private ScrollView1 As ScrollView
    Dim Header As Panel
    Dim Table As Panel
    Dim NumberOfColumns, RowHeight, ColumnWidth As Int
    Dim HeaderColor, TableColor, FontColor, HeaderFontColor As Int
    Dim FontSize As Float
'    Type RowCol (Row As Int, Col As Int)
    Dim Alignment As Int
    Dim SelectedRow As Int
    Dim SelectedRowColor As Int
   
    'Table Settings
    HeaderColor = Colors.Gray
    NumberOfColumns = 8
    RowHeight = 30dip
    TableColor = Colors.White
    FontColor = Colors.Black
    HeaderFontColor = Colors.White
    FontSize = 14
    Alignment = Gravity.CENTER 'change to Gravity.LEFT or Gravity.RIGHT for other alignments.
    SelectedRowColor = Colors.Blue
   
    Private Button1 As Button
End Sub

Sub Activity_Create(FirstTime As Boolean)
    'Do not forget to load the layout file created with the visual designer. For example:
   
    Parser.Initialize
    Activity.LoadLayout("ProductManagement")
   
    ScrollView1.Initialize(0)
    Table = ScrollView1.Panel
    Table.Color = TableColor
    Activity.AddView(ScrollView1, 0%x, 25%y, 100%x, 70%y)
    ColumnWidth = ScrollView1.Width / NumberOfColumns
    SelectedRow = -1
    'add header
    SetHeader(Array As String("Product ID", "Carton Content", "Name", "Unit", "Tax", "Barcode", "Price", "in Stock"))
    ServiceLoad
   
   
End Sub

Sub Activity_Resume

End Sub

Sub Activity_Pause (UserClosed As Boolean)

End Sub
Sub ServiceLoad

    Dim job1 As HttpJob
    job1.Initialize("Job1", Me)
    job1.Download2("XXX", _
    Array As String("KeyCode", "XXX", "whereSql", "Customer_ID=1"))
   
End Sub
'################################################################################## ScrollView Start ##########################################################################################################
Sub Cell_Click
    Dim rc As RowCol
    Dim l As Label
    l = Sender
    rc = l.Tag
    SelectRow(rc.Row)
    Activity.Title = "Cell clicked: (" & rc.Row & ", " & rc.Col & ")"
End Sub
Sub Header_Click
    Dim l As Label
    Dim col As Int
    l = Sender
    col = l.Tag
    Activity.Title = "Header clicked: " & col
End Sub
Sub SelectRow(Row As Int)
    'remove the color of previously selected row
    If SelectedRow > -1 Then
        For col = 0 To NumberOfColumns - 1
            GetView(SelectedRow, col).Color = Colors.Transparent
        Next
    End If
    SelectedRow = Row
    For col = 0 To NumberOfColumns - 1
        GetView(Row, col).Color = SelectedRowColor
    Next
End Sub
Sub GetView(Row As Int, Col As Int) As Label
    Dim l As Label
    l.Initialize("")
    ScrollView1.Initialize(100%x)
    l = Table.GetView(Row * NumberOfColumns + Col)
    Return l
End Sub
Sub AddRow(Values() As String)
    If Values.Length <> NumberOfColumns Then
        Log("Wrong number of values.")
        Return
    End If
    Dim lastRow As Int
    lastRow = NumberOfRows
    For i = 0 To NumberOfColumns - 1
        Dim l As Label
        l.Initialize("cell")
        l.Text = Values(i)
        l.Gravity = Alignment
        l.TextSize = FontSize
        l.TextColor = FontColor
        Dim rc As RowCol
        rc.Initialize
        rc.Col = i
        rc.Row = lastRow
        l.Tag = rc
        Table.AddView(l, ColumnWidth * i, RowHeight * lastRow, ColumnWidth, RowHeight)
    Next
    Table.Height = NumberOfRows * RowHeight
End Sub
Sub SetHeader(Values() As String)
    If Header.IsInitialized Then Return 'should only be called once
    Header.Initialize("")
    For i = 0 To NumberOfColumns - 1
        Dim l As Label
        l.Initialize("header")
        l.Text = Values(i)
        l.Gravity = Gravity.CENTER
        l.TextSize = FontSize
        l.Color = HeaderColor
        l.TextColor = HeaderFontColor
        l.Tag = i
        Header.AddView(l, ColumnWidth * i, 0, ColumnWidth, RowHeight)
    Next
    Activity.AddView(Header, ScrollView1.Left, ScrollView1.Top - RowHeight, ScrollView1.Width, RowHeight)
End Sub
Sub NumberOfRows As Int
    Return Table.NumberOfViews / NumberOfColumns
End Sub
Sub SetCell(Row As Int, Col As Int, Value As String)
    GetView(Row, Col).Text = Value
End Sub
Sub GetCell(Row As Int, Col As Int) As String
    Return GetView(Row, Col).Text
End Sub
Sub ClearAll
    For i = Table.NumberOfViews -1 To 0 Step -1
        Table.RemoveViewAt(i)
    Next
    Table.Height = 0
    SelectedRow = -1
End Sub

Sub TableFilling
    'add rows    Auslagern in ein Modul nach XML Parser
'    For i = 1 To 100

        AddRow(Array As String(PD_ProductID, PD_CartonContent, PD_Name, PD_Unit, PD_Tax, PD_Barcode, PD_Price, PD_inStock))
'    Next
        'set the value of a specific cell
'    SetCell(0, 3, "New value")
    'get the value
    Log("Cell (1, 2) value = " & GetCell(1, 2))

End Sub
'################################################################################## ScrollView END ##########################################################################################################

'################################################################################## XMLParser START ##########################################################################################################
Sub Parser_StartElement (Uri As String, Name As String, Attributes As Attributes)

End Sub

Sub Parser_EndElement (Uri As String, Name As String, Text As StringBuilder)

    If Name = "ProductID" Then
        PD_ProductID = Text.ToString
    End If
    If Name = "CartonContent" Then
        PD_CartonContent = Text.ToString
    End If
    If Name = "ProductName" Then
        PD_Name = Text.ToString
    End If
    If Name = "Unit" Then
        PD_Unit = Text.ToString
    End If
    If Name = "TaxRate" Then
        PD_Tax = Text.ToString
    End If
    If Name = "PD_Barcode" Then
        PD_Barcode = Text.ToString
    End If
    If Name = "PD_Price" Then
        PD_Price = Text.ToString
    End If
    If Name = "inStock" Then
        PD_inStock = Text.ToString
    TableFilling       
    End If
End Sub
Sub JobDone (Job As HttpJob )
''Msgbox ("job","qq")

   Log("JobName = " & Job.JobName & ", Success = " & Job.Success)
   If Job.Success = True Then
   Parser.Parse(StringToInputStream(Job.GetString), "Parser") ' PArser'e gonderiyorsun
  '' Msgbox ("jobsucces","qq")
     Log(Job.GetString)
    '\|%&amp;
        'StartActivity("HomeScreen")
   Else
      Log("Error: " & Job.ErrorMessage)
      ToastMessageShow("Error: " & Job.ErrorMessage, True)
   End If
   Job.Release
End Sub   
Sub StringToInputStream (s As String) As InputStream
Try

   Dim In As InputStream
   Dim data() As Byte = s.GetBytes("UTF8")
   In.InitializeFromBytesArray(data, 0, data.Length)
   Return In
Catch
Log(LastException.Message )
End Try

End Sub
'################################################################################## XMLParser END ##########################################################################################################

'################################################################################## ADD NEW Account ##########################################################################################################
Sub Button1_Click
    StartActivity("AccountsInsert")
End Sub
 

klaus

Expert
Licensed User
Longtime User
This sub is wrong:
B4X:
Sub GetView(Row As Int, Col As Int) As Label
    Dim l As Label
    l.Initialize("")
    ScrollView1.Initialize(100%x)
    l = Table.GetView(Row * NumberOfColumns + Col)
    Return l
End Sub
You should remove: ScrollView1.Initialize(100%x)
Correct sub:
B4X:
Sub GetView(Row As Int, Col As Int) As Label
    Dim l As Label
    l.Initialize("")
    l = Table.GetView(Row * NumberOfColumns + Col)
    Return l
End Sub
 
Status
Not open for further replies.
Top