Bug? Standard ListView Requires sleep for Color Change (B4A-8.50)

MrKim

Well-Known Member
Licensed User
Longtime User
I added the code to change colors (If O.OSStatus = "C" Then...) but it had no effect until I added the
Sleep(0).
All lines remained the default - white.
Not a big deal but it took awhile to figure out what was going on.
B4X:
Sub Globals
  Dim List1 As ListView
.
.
.
        Do While Crsr.NextRow
            O.OSID = Crsr.GetLong("Os_ID")
            O.JobNum = Crsr.GetString("Os_JobNum")
            O.Rel = Crsr.GetString("Os_ReleaseNum")
            O.Os_SeqNum = Crsr.GetString("Os_SeqNum")
            O.Tk_WCName = Crsr.GetString("Os_WCCode")
            O.OSStatus = Crsr.GetString("Os_Status")
            If O.OSStatus = "C" Then
                List1.TwoLinesLayout.Label.TextColor = Colors.Red
            Else
                List1.TwoLinesLayout.Label.TextColor = Colors.White
            End If
            Sleep(0)
            If Crsr.GetInt("Os_SubContract") = 0 Then
                List1.AddTwoLines2(NumberFormat(Crsr.GetString("Os_SeqNum"),0 ,0 ) & " Op: " & Crsr.GetString("Os_WCCode") & IIF(O.OSStatus = Null, "", "-Status: " & O.OSStatus), "Start By: " & Crsr.GetString("Os_StartbyDate") & " Setup: " & NumberFormat(Crsr.GetString("Os_SetupTime"), 0, 2) & " Run: " & NumberFormat(Crsr.GetString("Os_RunTime"), 0, 2), O)
            End If
.
.
.
More was revealed. See next post.
 
Last edited:

MrKim

Well-Known Member
Licensed User
Longtime User
Well, the problem turned out to be more difficult to solve than I thought.
Turns out the code above was turning the List Item red BEFORE the one that was supposed to be Red.
So I tried this:
B4X:
        Do While Crsr.NextRow
            O.OSID = Crsr.GetLong("Os_ID")
            O.JobNum = Crsr.GetString("Os_JobNum")
            O.Rel = Crsr.GetString("Os_ReleaseNum")
            O.Os_SeqNum = Crsr.GetString("Os_SeqNum")
            O.Tk_WCName = Crsr.GetString("Os_WCCode")
            O.OSStatus = Crsr.GetString("Os_Status")
            If Crsr.GetInt("Os_SubContract") = 0 Then
                List1.AddTwoLines2(NumberFormat(Crsr.GetString("Os_SeqNum"),0 ,0 ) & " Op: " & Crsr.GetString("Os_WCCode") & IIF(O.OSStatus = Null, "", "-Status: " & O.OSStatus), "Start By: " & Crsr.GetString("Os_StartbyDate") & " Setup: " & NumberFormat(Crsr.GetString("Os_SetupTime"), 0, 2) & " Run: " & NumberFormat(Crsr.GetString("Os_RunTime"), 0, 2), O)
            End If
            Sleep(0)
            If O.OSStatus = "C" Then
                List1.TwoLinesLayout.Label.TextColor = Colors.Red
            Else
                List1.TwoLinesLayout.Label.TextColor = Colors.White
            End If
And it turned the Item AFTER the one that was supposed to be red red.
THIS works:
B4X:
        Do While Crsr.NextRow
            O.OSID = Crsr.GetLong("Os_ID")
            O.JobNum = Crsr.GetString("Os_JobNum")
            O.Rel = Crsr.GetString("Os_ReleaseNum")
            O.Os_SeqNum = Crsr.GetString("Os_SeqNum")
            O.Tk_WCName = Crsr.GetString("Os_WCCode")
            O.OSStatus = Crsr.GetString("Os_Status")
            If Crsr.GetInt("Os_SubContract") = 0 Then
                List1.AddTwoLines2(NumberFormat(Crsr.GetString("Os_SeqNum"),0 ,0 ) & " Op: " & Crsr.GetString("Os_WCCode") & IIF(O.OSStatus = Null, "", "-Status: " & O.OSStatus), "Start By: " & Crsr.GetString("Os_StartbyDate") & " Setup: " & NumberFormat(Crsr.GetString("Os_SetupTime"), 0, 2) & " Run: " & NumberFormat(Crsr.GetString("Os_RunTime"), 0, 2), O)
            End If
            If O.OSStatus = "C" Then
                List1.TwoLinesLayout.Label.TextColor = Colors.Red
            Else
                List1.TwoLinesLayout.Label.TextColor = Colors.White
            End If
            Sleep(0)
 

OliverA

Expert
Licensed User
Longtime User
I don't think it is a bug. This has to do with events and how the usage or not usage of SLEEP impacts event processing. Setting the text color is an event (a guess here, due to what you are experiencing). If you do not use sleep and process your Do While loop, events are generated, but not executed until the Do While finishes processing and your code finishes and returns in such a way that event processing happens (by waiting for the next event) and then all the events are processed at once. Using SLEEP, you can "force" events to be processed. In your first listing (post #1) you create a "TextColor" event, use SLEEP to have it processed and then set your text. As you can see, the two items are out of sync. In your second example, you add text, use SLEEP to let the system process events and then create a "TextColor" event. Once more, creating the text and setting the color are out of sync. Finally, you create the text, then change the color and then use SLEEP to process the events in the correct order.
 

DonManfred

Expert
Licensed User
Longtime User
Not a bug. You can NOT define different colors for the same type of items in a Listview. ALL Items of the same type share the same color.

OneLine, twolines, twolineandbitmap.

Use xCustomListview and you have much more control. You even can use a different color on each item

Alternative: You can use CharsequenceBuilder to set the Text with different Colors.
B4X:
For i = 1 To 100
   ListView1.AddSingleLine(cs.Initialize.Color(Rnd(0xFF000000, -1)).Alignment("ALIGN_CENTER").Append($"Item #${i}"$).PopAll)
Next
 
Last edited:

MrKim

Well-Known Member
Licensed User
Longtime User
Not a bug. You can NOT define different colors for the same type of items in a Listview. ALL Items of the same type share the same color.

OneLine, twolines, twolineandbitmap.

Use xCustomListview and you have much more control. You even can use a different color on each item

Alternative: You can use CharsequenceBuilder to set the Text with different Colors.
B4X:
For i = 1 To 100
   ListView1.AddSingleLine(cs.Initialize.Color(Rnd(0xFF000000, -1)).Alignment("ALIGN_CENTER").Append($"Item #${i}"$).PopAll)
Next
Thank you!
This works like a charm:
B4X:
            If Crsr.GetInt("Os_SubContract") = 0 Then
   If O.OSStatus = "C" Then Clr = Colors.Red Else Clr = Colors.White
   cs.Initialize.Color(Clr).Append(NumberFormat(Crsr.GetString("Os_SeqNum"),0 ,0 ) & " Op: " & Crsr.GetString("Os_WCCode") & IIF(O.OSStatus = Null, "", "-Status: " & O.OSStatus)).PopAll
   List1.AddTwoLines2(cs, "Start By: " & Crsr.GetString("Os_StartbyDate") & " Setup: " & NumberFormat(Crsr.GetString("Os_SetupTime"), 0, 2) & " Run: " & NumberFormat(Crsr.GetString("Os_RunTime"), 0, 2), O)
End If
I just wish I understood why:p
 
Top