Android Question Problem using list / map

FERNANDO SILVEIRA

Active Member
Licensed User
Hello guys,

I've seen this issue in many other threads here, but now that I need it I'm unable to find the answer.

I cast labels on the activity and want to save their information for later retrieval (.text, .left, .top, etc).
I created a map with the fields I want to save.
I lstLetters.add information held in my mapLetters map, but after the main loop is complete, only the last occurence data is present in lstLetters.

What am I doing wrong? What is the correct why to save and retrieve from my lstLetters list?
B4X:
    Type LetterCoord(index As Int, letter As String, left As Int, top As Int, found As Boolean)

Sub Activity_Create(FirstTime As Boolean)

    Private mapLetters As LetterCoord
    Private lstLetters As List

' When running this loop, only information regarding last interation is listed
    For i = 0 To lstLetters.Size - 1
        Log("lstLetters " & i & ") " & lstLetters.Get(i))
    Next
End Sub

Sub DrawWord(word As String, left As Int, top As Int, empty As Boolean)
    For i = 0 To word.Length - 1
        lblLetter(i).Initialize("lblLetter")
        lblLetter(i).Text = word.SubString2(i, i+1)
        lblLetter(i).TextColor = Colors.White
        lblLetter(i).TextSize = 50
        lblLetter(i).Background=cd
        lblLetter(i).Gravity = Gravity.CENTER_HORIZONTAL
        lblLetter(i).left = left
        Activity.AddView(lblLetter(i), lblLetter(i).left, top, 45dip, 80dip)
        left = left + 55dip
        If empty <> True Then
' Want to save lblLetter(i) information on a list for later retrieval
            mapLetters.Initialize
            mapLetters.index = i
            mapLetters.letter = lblLetter(i).Text
            mapLetters.left = lblLetter(i).Left
            mapLetters.top = top
            mapLetters.found = False
' Not sure if I'm doing right because only the last interaction data is kept, others are overwritten
            lstLetters.Add(mapLetters)
            Log(i & ") " & mapLetters)
        End If
    Next
End Sub
 

Attachments

LucaMs

Expert
Licensed User
Premising that I do not focus so much on your code ...

1) mapLetters is not a Map, it is a variable of your custom type LetterCoord (better name: tLetterCoord, so the "t" will help you to remember that it is a custom type :))

2) if you want a new object in a loop (Do While, Do Until, For-Next) you have also to declare it (Dim) inside the loop, not only initialize it.
 

Eme Fibonacci

Well-Known Member
Licensed User
Try this.
You must create new instances of your variable.

B4X:
Dim mapLetters as LetterCoord  'Add
mapLetters.Initialize
mapLetters.index = i
mapLetters.letter = lblLetter(i).Text
mapLetters.left = lblLetter(i).Left
mapLetters.top = top
mapLetters.found = False

lstLetters.Add(mapLetters)
 

FERNANDO SILVEIRA

Active Member
Licensed User

Erel

Administrator
Staff member
Licensed User
I've seen this issue in many other threads here,
Relevant video tutorial that goes over this common mistake:

let's see the correct answer (from @Erel)
The exact answer is a bit more complicated.
In the case of custom types @Eme Fibonacci is right. Dim t As MyType creates a new type instance. t.Initialize "initializes" the fields. Note that if the type only hold primitive fields then you don't really need to initialize it (though it is a good practice to always initialize objects).

There are many types in B4X which are wrapper types. All views for example are wrapper types:
B4X:
Dim b As Button 'creates a new instance of the wrapper object
b.Initialize 'creates a new native button object and sets it to the wrapper object
b.Initialize 'replaces the previous native button with a new one
In the case of wrappers it is closer to what Luca wrote.

The bottom line is that you need to Dim and Initialize whenever you want a new instance.
 
Top