Android Question xCustomListView needs a long time to show only 300 items ...

JOTHA

Well-Known Member
Licensed User
Longtime User
Erel said in the tutorial video that xCustomListView is fast enough if there are not so much items (< 1000) to show.

I've now switched from a "normal" ListView (which has shown about 300 records from a SQLite database in less than 1-2 seconds) to a xCustomListView ...

However, the xCustomListView needs about 34 seconds to show the same items (that's too long for the app)!

It concerns the representation of the following information from the SQLite:
6 text fields and 2 links to pictures (they are in an internal folder).

Here is the code:
B4X:
#Region  Project Attributes
    #ApplicationLabel: B4A Example
    #VersionCode: 1
    #VersionName:
    'SupportedOrientations possible values: unspecified, landscape or portrait.
    #SupportedOrientations: unspecified
    #CanInstallToExternalStorage: False
#End Region

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

Sub Process_Globals

    Dim SQL1 As SQL
    Dim Cursor As Cursor

End Sub

Sub Globals
   
    Private xCustomListView As CustomListView
    Private Panel_003a_Label_Ueberschrift As Label  '-- eine Initialisierung ist zwar unnötig, aber bei der Ausführung der App wird ein ERROR generiert --
    Private Panel_003a_Label_001 As Label
    Private Panel_003a_ImageView_014 As ImageView
    Private Panel_003a_Label_002 As Label
    Private Panel_003a_ImageView_009 As ImageView
    Private Panel_003a_Label_014 As Label
    Private Panel_003a_Label_Hinweis As Label
    Private Panel_003a_Label_004 As Label
    Private Panel_003a_Label_IDNR As Label
   
End Sub

Sub Activity_Create(FirstTime As Boolean)
   
    Log("Kopiere die Datenbank in File.DirRootExternal")

    File.Copy(File.DirAssets, "SQLite_MUSTER.sl3", _
                    File.DirRootExternal, "SQLite_MUSTER.sl3")
    Log("Datenbank in File.DirRootExternal kopiert!")

    If FirstTime Then
        SQL1.Initialize(File.DirRootExternal, "SQLite_MUSTER.sl3", True)
    End If
    If SQL1.IsInitialized = False Then
        SQL1.Initialize(File.DirRootExternal, "SQLite_MUSTER.sl3", True)
    End If
    SQL1.Initialize(File.DirRootExternal, "SQLite_MUSTER.sl3", True)

    Activity.LoadLayout("layout_003_datensaetze_zeigen")
   
    xCustomListView.Clear
   
'-- Überschrift einfügen und View initialisieren --
    Panel_003a_Label_Ueberschrift.Initialize("CreateListItem")
    Panel_003a_Label_001.Initialize("CreateListItem")  '-- eine Initialisierung ist zwar unnötig, aber bei der Ausführung der App wird ein ERROR generiert --
    Panel_003a_Label_002.Initialize("CreateListItem")
    Panel_003a_Label_014.Initialize("CreateListItem")
    Panel_003a_Label_004.Initialize("CreateListItem")
    Panel_003a_Label_IDNR.Initialize("CreateListItem")
    Panel_003a_Label_Hinweis.Initialize("CreateListItem")
    Panel_003a_ImageView_009.Initialize("CreateListItem")
    Panel_003a_ImageView_014.Initialize("CreateListItem")
   
    Cursor = SQL1.ExecQuery ("SELECT * FROM MUSTER_Tabelle")
       
    Try
        SQL1.BeginTransaction

        For i = 0 To Cursor.RowCount - 1
            Cursor.Position = i
           
        '-- Zähler für die Auswahlliste generieren --
            Dim Counter As String
            Counter = i +1
           
        '-- die xCustomListView aufbauen --
            xCustomListView.Add(CreateListItem(Panel_003a_Label_Ueberschrift.Text, Activity.Width, 315dip), ""&Cursor.GetString("IDNR")&"")
           
        '-- wenn keine Internet-Adresse vorhanden ist -- Feld007 --
            If Cursor.GetString("Feld007") = "- keine Internet-Adresse -" Then
                Panel_003a_Label_Ueberschrift.Text = "  "&Counter&". Datensatz ist OHNE Internet-Zugang"
                Panel_003a_Label_Ueberschrift.Color = Colors.Red
            Else If Cursor.GetString("Feld007") = "" Then
                Panel_003a_Label_Ueberschrift.Text = "  "&Counter&". Datensatz ist OHNE Internet-Zugang"
                Panel_003a_Label_Ueberschrift.Color = Colors.Red
            Else
                Panel_003a_Label_Ueberschrift.Text = "  "&Counter&". Datensatz ist MIT Internet-Zugang"
                Panel_003a_Label_Ueberschrift.Color = Colors.Blue
            End If
           
        '-- Daten_in_die_xCustomListView_einfuegen --
            Daten_in_die_xCustomListView_einfuegen
            Log("-----------------------------------------------------------------------------")
            Log(""&Counter&". Datensatz gelistet")

        Next
        SQL1.TransactionSuccessful
    Catch
        Log(""&LastException.Message&"")
    End Try
    SQL1.EndTransaction
    Cursor.Close

End Sub

Sub xCustomListView_ItemClick (Index As Int, Value As Object)
    Activity.Title = Value
    xCustomListView.AsView.BringToFront
End Sub

Sub Daten_in_die_xCustomListView_einfuegen

'-- Daten in die Textelder zuweisen --
    Panel_003a_Label_001.Text = ""&Cursor.GetString("Feld001")&""
    Panel_003a_Label_002.Text = "Benutzer:"&CRLF&""&Cursor.GetString("Feld002")&""
    Panel_003a_Label_004.Text = "Kategorie:"&CRLF&""&Cursor.GetString("Feld004")&""
    Panel_003a_Label_IDNR.Text = "ID: "&Cursor.GetString("IDNR")&""
       
'-- Eigenes Bild zuweisen -- Feld014 --
    Log("Eigenes Bild zuweisen - Feld014: "&Cursor.GetString("Feld014")&"")
    If File.Exists(File.DirAssets, ""&Cursor.GetString("Feld014")&"") Then
        Panel_003a_Label_014.Text = "Ein Bild ist vorhanden"
        Panel_003a_ImageView_014.Bitmap = LoadBitmap(File.DirAssets, ""&Cursor.GetString("Feld014"))
        Panel_003a_Label_014.Typeface = Typeface.DEFAULT
    Else
        Panel_003a_Label_014.Text = "Es ist KEIN Bild vorhanden!"
    End If
           
'-- Kategorie-Icon zuweisen -- Feld009 --
    Log("Kategorie-Icon zuweisen - Feld009: "&Cursor.GetString("Feld014")&"")
    If File.Exists(File.DirAssets, ""&Cursor.GetString("Feld009")&"") Then
        Log("If FILE EXISTST ==> "&File.Exists(File.DirAssets, ""&Cursor.GetString("Feld009")&"")&"")
        Panel_003a_Label_014.Text = "Ein Bild ist vorhanden"
        Panel_003a_ImageView_009.Bitmap = LoadBitmap(File.DirAssets, ""&Cursor.GetString("Feld009"))
        Panel_003a_Label_014.Typeface = Typeface.DEFAULT
    Else
        Panel_003a_Label_004.Text = "Es ist KEIN Kategorie-Bild vorhanden!"
        Log("Inhalt von Feld009: "&Cursor.GetString("Feld009")&"")
        Log("Es ist KEIN Kategorie-Bild vorhanden!")
    End If

End Sub

Sub CreateListItem(Text As String, Width As Int, Height As Int) As Panel
   
    Dim p As Panel
    p.Initialize("")
    p.SetLayout(0, 0, Width, Height)
    p.LoadLayout("layout_003a_inhalt_p3_xclv3")
    Panel_003a_Label_001.Text = Text
    Return p
   
End Sub

Sub Activity_Resume
End Sub

Sub Activity_Pause (UserClosed As Boolean)
End Sub

I have packed a small example app as a zip-file for testing, but unfortunately I can not upload it because it's too large (743 kB). If someone wants to test it, I am happy to send the file via e-mail.
(Or can somebody tell me how to split the zip-file?)

Can someone tell me why xCustomListView needs such a long time to show only 300 items ...? o_O
 

DonManfred

Expert
Licensed User
Longtime User
WHY you are creating a TRANSACTION if you just READ from the DB??? It is NOT needed when reading...

Also initialising the labels, edits, IVs is the wrong way.
The Object are available after calling CreateItem
 
Upvote 0

Peter Simpson

Expert
Licensed User
Longtime User
Erel said in the tutorial video that xCustomListView is.....

If I'm not mistaken (and I'm not), Erel also mentioned in the video about using lazy loading which you should have implemented and should be using. You should use lazy loading and also use the routine for removing rows that are no longer visible.

Trust me when I say that lazy loading works great for long lists (rows of data currently up to 37163 in one of clients databases and xCustomListView with lazy loading works great, new rows are being added every single day). But why anybody would need to manually scroll that far down a list has always baffled me in the first place.

Hint:
I personally always include a live active search box to filter lists down to size, this makes it easier for the end user to shift through/scroll down through rows of data as only the relevant data is displayed in xCustomListView, for example all invoices that included 'anywhere' or just 'where' in the company name, or any invoice that included 'birmingham' or just 'birm' in the address, just use the Like %% operator to search multiple fields and return unique results.

Sorry for the slight diversion, but it should come in handy for your clients or for yourself if you ever decide to go down that route...
 
Last edited:
Upvote 0

JOTHA

Well-Known Member
Licensed User
Longtime User
WHY you are creating a TRANSACTION if you just READ from the DB??? It is NOT needed when reading ... Also initialising the labels, edits, IVs is the wrong way.
The Object are available after calling CreateItem
Hi DonManfred,
thank you for your response.
I know, that I don't have to initialize when the views are coming from the Visual Designer, buti If I don't initialize ... then comes an error-message: "java.lang.RuntimeException: java.lang.RuntimeException: Object should first be initialized (Label)."

If I initialize only 1 label called "Panel_003a_Label_Ueberschrift.Initialize("CreateListItem")", there is no error-message ...

And the reason for the SQL-TRANSACTION was to make it faster, but there is no effect when I use it.

I've deleted the TRANSACTION, the TRY/CATCH and the initializing of the other Labels and ImageViews, but there is no effect for more speed.
 
Upvote 0

JOTHA

Well-Known Member
Licensed User
Longtime User
You should use lazy loading and also use the routine for removing rows that are no longer visible.
Hi Peter,
thank you very much for your tipps!

I personally always include a live active search box to filter lists down to size
... I did the same to this list, but sometimes the users want to see how much the whole list contains ...
 
Upvote 0
Top