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

  • APP04 JogoDasPalavras.zip
    144.2 KB · Views: 124

OliverA

Expert
Licensed User
Upvote 0

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.
 
Upvote 0

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)
 
Upvote 0

FERNANDO SILVEIRA

Active Member
Licensed User
Upvote 0

LucaMs

Expert
Licensed User
Dim mapLetters as LetterCoord 'Here you are creating new instances (objects).
mapLetters.Initialize 'Here you are initializing them
More exactly, I think:
Dim mapLetters as LetterCoord 'Here you are DECLARING a variable of type LetterCoord.
mapLetters.Initialize 'Here you are CREATING an instance (object) of type LetterCoord
 
Upvote 0

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.
 
Upvote 0
Top