B4A Library [Class] Flexible Table

RauchG

Active Member
Licensed User
Longtime User
Hello Klaus,

I use your [Class] Flexible Table in version 1.36. Success with SQLite (db3).

Now I'm building my database with "AutoScaleAll" for all devices to. In a "Galaxy S2, 4.0.4, 480x800, API 15", the table is not loaded. The S2 unit as I have.

With Genymotion I have tried a virtual "Google Nexus S, 4.1.1, 480x800, API 16". The table is not loaded.

Do you have any idea?

Greeting RauchG
 

RauchG

Active Member
Licensed User
Longtime User
Hello Klaus,

I was about to write a small example database. Since I've discovered a bug with me. A silly spelling mistakes.

Your [Class] Flexible Table works perfectly with the above devices.

Greeting RauchG
 

vecino

Well-Known Member
Licensed User
Longtime User
Hello, every time something new is included, it becomes slower.

Is there a program to debug and find where it is slower?
 

vecino

Well-Known Member
Licensed User
Longtime User
Hello is not slow in presenting the records read.
It's slow to draw the header, change font size, column widths, align text to one side or another, etc.
Example of code:
B4X:
Sub LoadTable( Dim cTabla As String )
    Dim cSql As String   
    Dim c0,c1,c2,c3,c4 As String    ' variables para recoger datos del registro   
    Dim iW1,iW2,iW3,iW4,iW5 As Int    ' anchos de columnas
    Dim iX As Int   
    Dim iAlineado() As Int    ' alineado de cada columna
    '
    cSql = "select codigo, nombre, telefono1, telefono2, email from "&cTabla&" order by codigo"
    If bFiltrado Then    cSql = cSqlFiltro       
    '   
    If Q.IsInitialized Then Q.Close
    '
    Q = globales.DBconex.ExecQuery(cSql)
    '   
    If Q.RowCount>0 Then
        If Not (tbTabla.IsInitialized) Then
            tbTabla.Initialize(Me,"tbTabla",5,Gravity.CENTER,False)    ' 5 columnas
            tbTabla.AddToActivity(pnLista,0,0,pnLista.Width,pnLista.Height)           
            tbTabla.SetHeader(Array As String(msg(5),msg(6),msg(67)&"1",msg(67)&"2",msg(68)))    'codigo,nombre,telefono1,telefono2,email
        End If
        '       
        tbTabla.SelectedRowColor  = globales.iColorSeleccionado
        tbTabla.SelectedCellColor = globales.iColorSeleccionado
        '
        tbTabla.RowColor1 = globales.iColorNon
        tbTabla.RowColor2 = globales.iColorPar
        '
        tbTabla.ClearAll
        '
        For iX=0 To Q.RowCount-1
            Q.Position=iX       
            ' asignar valores
            c0 = (Q.GetString2(0)).trim                        ' codigo
            c1 = (Q.GetString2(1)).trim                        ' nombre
            c2 = (Q.GetString("telefono1")).trim    ' telefono1
            c3 = (Q.GetString("telefono2")).trim    ' telefono2
            c4 = (Q.GetString("email")).trim            ' email            
            ' añadir a la fila
            tbTabla.AddRow(Array As String(c0,c1,c2,c3,c4))
        Next
        ' ancho de las columnas       
        iW1 = (10*pnFondo.Width)/100    'codigo
        iW2 = (30*pnFondo.Width)/100    'nombre
        iW3 = (10*pnFondo.Width)/100    'telefono1
        iW4 = (10*pnFondo.Width)/100    'telefono2
        iW5 = (40*pnFondo.Width)/100    'email       
        tbTabla.SetColumnsWidths(Array As Int(iW1,iW2,iW3,iW4,iW5))
        '       
        iAlineado = Array As Int( Gravity.center,Gravity.left,Gravity.LEFT,Gravity.LEFT,Gravity.LEFT)
        tbTabla.SetCellAlignments( iAlineado )
    End If
    '
    If Q.IsInitialized Then    Q.Close
End Sub
 

klaus

Expert
Licensed User
Longtime User
It's slow to draw the header, change font size, column widths, align text to one side or another, etc.
I'm not sure I understand what you mean.
Do you mean that it needs more code to do it or the time to fill the table.
- If it's code, you need to change only the parameters different from the default ones.
If you want to change them you need methods to do it.
How would you have done it differently ?

- If it's the speed, try to move these lines before you fill the rows.
B4X:
' ancho de las columnas      
iW1 = (10*pnFondo.Width)/100    'codigo
iW2 = (30*pnFondo.Width)/100    'nombre
iW3 = (10*pnFondo.Width)/100    'telefono1
iW4 = (10*pnFondo.Width)/100    'telefono2
iW5 = (40*pnFondo.Width)/100    'email      
tbTabla.SetColumnsWidths(Array As Int(iW1,iW2,iW3,iW4,iW5))
'      
iAlineado = Array As Int( Gravity.center,Gravity.left,Gravity.LEFT,Gravity.LEFT,Gravity.LEFT)
tbTabla.SetCellAlignments( iAlineado )
 

vecino

Well-Known Member
Licensed User
Longtime User
Hi, sorry if I did not explain well. My English is terrible.

The problem is that this code takes 3 seconds to draw on the screen.
If I delete fonts, alignment, etc. code takes 1 second to draw on the screen.

Early versions of "Table" is drew much faster. The features added to the latest versions have slowed displaying on the screen.

The same code, commenting some options, takes 1 second to draw on screen.

B4X:
Sub LoadTable( Dim cTabla As String )
    Dim cSql As String 
    Dim c0,c1,c2,c3,c4 As String    ' variables para recoger datos del registro 
'    Dim iW1,iW2,iW3,iW4,iW5 As Int    ' anchos de columnas
    Dim iX As Int 
'    Dim iAlineado() As Int    ' alineado de cada columna
    '
    cSql = "select codigo, nombre, telefono1, telefono2, email from "&cTabla&" order by codigo"
    If bFiltrado Then    cSql = cSqlFiltro     
    ' 
    If Q.IsInitialized Then Q.Close
    '
    Q = globales.DBconex.ExecQuery(cSql)
    ' 
    If Q.RowCount>0 Then
        If Not (tbTabla.IsInitialized) Then
            tbTabla.Initialize(Me,"tbTabla",5,Gravity.CENTER,False)    ' 5 columnas
            tbTabla.AddToActivity(pnLista,0,0,pnLista.Width,pnLista.Height)         
            tbTabla.SetHeader(Array As String(msg(5),msg(6),msg(67)&"1",msg(67)&"2",msg(68)))    'codigo,nombre,telefono1,telefono2,email
        End If
        '     
'        tbTabla.SelectedRowColor  = globales.iColorSeleccionado
'        tbTabla.SelectedCellColor = globales.iColorSeleccionado
        '
'        tbTabla.RowColor1 = globales.iColorNon
'        tbTabla.RowColor2 = globales.iColorPar
        '
        tbTabla.ClearAll
        '
        For iX=0 To Q.RowCount-1
            Q.Position=iX     
            ' asignar valores
            c0 = (Q.GetString2(0)).trim                        ' codigo
            c1 = (Q.GetString2(1)).trim                        ' nombre
            c2 = (Q.GetString("telefono1")).trim    ' telefono1
            c3 = (Q.GetString("telefono2")).trim    ' telefono2
            c4 = (Q.GetString("email")).trim            ' email          
            ' añadir a la fila
            tbTabla.AddRow(Array As String(c0,c1,c2,c3,c4))
        Next
        ' ancho de las columnas     
'        iW1 = (10*pnFondo.Width)/100    'codigo
'        iW2 = (30*pnFondo.Width)/100    'nombre
'        iW3 = (10*pnFondo.Width)/100    'telefono1
'        iW4 = (10*pnFondo.Width)/100    'telefono2
'        iW5 = (40*pnFondo.Width)/100    'email     
'        tbTabla.SetColumnsWidths(Array As Int(iW1,iW2,iW3,iW4,iW5))
        '     
'        iAlineado = Array As Int( Gravity.center,Gravity.left,Gravity.LEFT,Gravity.LEFT,Gravity.LEFT)
'        tbTabla.SetCellAlignments( iAlineado )
    End If
    '
    If Q.IsInitialized Then    Q.Close
End Sub
 

vecino

Well-Known Member
Licensed User
Longtime User
Thank you very much for your advice.
I am going to implement.
 

ivan.tellez

Active Member
Licensed User
Longtime User
Hello, every time something new is included, it becomes slower.

Yes, vecino is right, I'm not shure why, but in some devices this could be really slow. For example in my Galaxy S4. I found that the problem is not on the render itself, its on the setup of the table.
Folowing the code, I found that calling:

B4X:
Table1.Initialize
Table1.setRowColor1
Table1.setRowColor2
Table1.setSelectedRowColor
Table1.setSelectedCellColor
Table1.AddToActivity
Table1.LoadSQLiteDB

Will internally call innerClearAll SEVEN TIMES, doing the initialization really slow.

Could be possible to add a "Config" stage to the table?

Maybe something like:

B4X:
Table1.Initialize2(...)   'Cant render data until finish config, DONT call innerClearAll
Table1.setRowColor1   'If initialized with Initialize2, this subs will not call innerClearAll
Table1.setRowColor2   'And nothing will be rendered until finish config.
Table1.setSelectedRowColor
Table1.setSelectedCellColor
Table1.AddToActivity
Table1.COMMIT 'Or FinishConfig. In here, will call innerClearAll and afther this, will render
Table1.LoadSQLiteDB



Not really shure this is the best solution, or maybe im missing something. but the innerClearAll executed 7 times before the data is actually rendered its a HUGE botttle neck.
 
Last edited:

ivan.tellez

Active Member
Licensed User
Longtime User
Annother dificulty is when you are using setRowColor1 and setRowColor2. In some cases, setSelectedRowColor will break the color theme.

In this case, could be possible to add a setSelectedRowColor2 to be used on the odd rows?

Also, selection its not really usefull in some tables. Maybe you could add a property to avoid using the SelectedDrawable, maybe AllowRowSelect.

Somenthing like this in ShowRow:

B4X:
    If Row Mod 2 = 0 Then
        If AllowRowSelect = True AND (SelectedRows.indexof(Row) <> -1 )Then
            rowColor = SelectedDrawable1
        Else
            rowColor = Drawable1
        End If
    Else
        If AllowRowSelect = True AND (SelectedRows.indexof(Row) <> -1 )Then
            rowColor = SelectedDrawable2
        Else
            rowColor = Drawable2
        End If
    End If
 

vecino

Well-Known Member
Licensed User
Longtime User
Thank you very much for your information.
I will test with your recommendations.
 

ivan.tellez

Active Member
Licensed User
Longtime User
Will internally call innerClearAll SEVEN TIMES, doing the initialization really slow.

Hi @klaus, I was playing around with the code, to prove this, and its true, I delete all the calls to innerClearAll but the one in AddToView, with the original code, it took about to 3 seconds to initialize the table and show data. After deleteting al the calls to innerClearAll this time dropped to less than half seccond.

There is no need for a "FinishConfig" sub. I think that all the config subs (setRowColor1,setRowColor2, setSelectedRowColor, setSelectedCellColor, etc.) should behave different if they are called BEFORE the AddToActivity sub.

If the table is not already attached to the Activity, it has no sense to update its look, avoiding useless innerClearAll calls

But when the table is already visible, the config subs of course had to change the look of the table inmediatly.
 

klaus

Expert
Licensed User
Longtime User
Can you try this version ?
I added an AllowSelection property, it's True by default.
I don't think that a second color for selected rows is very useful but more confusing.
 

Attachments

  • TableV1_37.zip
    43.6 KB · Views: 220
Last edited:

ivan.tellez

Active Member
Licensed User
Longtime User
Can you try this version ?

This is a huge optimization. Now, validating if the pnlTable Is Initialized, ou can save a lot of unnecessary code. Now the table is loading much faster.

The AllowSelection property its really usefull. Its also a optimization when your app dont use a selection. I only see a little drawback, its perfect for displaying data, but when you use the CellClick event, the user expect some kind of feedback. For example, In the Version 1.35, I disabled the SelectedDrawable, and left only the SelectedCellDrawable to archive this effect.

I think that your solution is more efficient disabling all the Selection. Can you think in a way to give that little visual feedback on the CellClick?

Thanks
 
Last edited:

stu14t

Active Member
Licensed User
Longtime User
Has anyone adapted the StateManager to save the table state or would it be easier to save the table as a csv then reload it?

The reason I ask I have rotation problem as the StateManager successfully saves everything else but the Table.
 
Last edited:

stu14t

Active Member
Licensed User
Longtime User
Thanks Klaus,

I'm just trying a different way; all my data is held in a global array so i'm simply re-adding the data from the array back into the table after the activity resumes.

A much easier way for me
 
Cookies are required to use this site. You must accept them to continue using the site. Learn more…