Android Question B4XTable Autofit Column Width

mmieher

Active Member
Licensed User
Longtime User
I struggled with this for awhile. https://www.b4x.com/android/forum/t...size-columns-based-on-content.102678/#content

I am really not worthy of changing Erel's code, but here is what worked for me. It also considers the width of the column header.

B4X:
Sub TableView_DataUpdated
    Log("TableView_DataUpdated")
    '    Name of B4XTable is TableView
    
    Dim tbl As B4XTable = Sender.As(B4XTable)
    
    Dim ShouldRefresh As Boolean
    'NOT NEEDED:  NameColumn and NumberColumn are global B4XTableColumns that we want to measure
    For Each column As B4XTableColumn In tbl.Columns
        Dim MaxWidth As Int
        For i = 0 To TableView.VisibleRowIds.Size - 1
            Dim RowId As Long = tbl.VisibleRowIds.Get(i)
        '' NOT NEEDED    If RowId > 0 Then
                Dim pnl As B4XView = column.CellsLayouts.Get(i + 1)
                Dim lbl As B4XView = pnl.GetView(0)
                Dim txt As String = TableView.GetRow(RowId).Get(column.Id)
                MaxWidth = Max(MaxWidth, cvs.MeasureText(txt, lbl.Font).Width + 10dip)
        ''    End If
        Next
        
        '    Get Header Width
        Dim txt As String = column.Title
        MaxWidth = Max(MaxWidth, cvs.MeasureText(txt, lbl.Font).Width + 10dip)
        
        If MaxWidth > column.ComputedWidth Or MaxWidth < column.ComputedWidth - 20dip Then
            column.Width = MaxWidth
            ShouldRefresh = True
        End If
        
    Next
    
    If ShouldRefresh Then
        tbl.Refresh
    End If
    
End Sub
 

Mahares

Expert
Licensed User
Longtime User
here is what worked for me. It also considers the width of the column header.
If you use 2 different fonts, one for the data and one for the title, it will not adjust the width of the header the way you have it in your code. For instance:
B4X:
B4XTable1.LabelsFont = xui.CreateDefaultFont(16)   'data displayed
B4XTable1.HeaderFont = xui.CreateDefaultFont(20)   'header
could wrap the title around. You need to address the title panel in your code so instead of this:
B4X:
'    Get Header Width
        Dim txt As String = column.Title
        MaxWidth = Max(MaxWidth, cvs.MeasureText(txt, lbl.Font).Width + 10dip)
you need these following lines to accommodate the title (header):
B4X:
' Get Header Width
Dim txt As String = column.Title
Dim p As B4XView = column.CellsLayouts.Get(0) 'title panel
Dim l As B4XView = p.GetView(0)
MaxWidth = Max(MaxWidth, cvs.MeasureText(txt, l.Font).Width + 10dip))
 
Upvote 0
Top