Italian aiuto per una lista xCostumListView

GIS

Well-Known Member
Licensed User
Ciao a tutti. Pensavo di aver risolto, invece.... Ho ripreso in mano la mia App per finire l'aggiornamento che era rimasto in sospeso da mesi. Ho solo un problema con la xCostumListView. Praticamente prendo su AddCastello aggiunge una scheda e qui tutto ok. Il problema è che volevo fare un refresh di tutto la lista non riesco a fargliela fare. Ormai sto impazzendo e ho bisogno di qualcuno con una mente più lucida. Molto probabilmente vi mettere le mani nei capelli appena prenderete visione del mio codice, con la scusa che sono consapevole dei miei limiti in programmazione, se non commentate mi fate un piacere...hahaha grazie.
B4X:
Sub AddCastello_Click
            
    Log("aggiungi. Schede totali "& CLV1.Size &" n. max castelli "&Main.NumeroMaxCastelli)
            
    NumeroSchede = CLV1.Size
    
    Log("inizio ADD")
    For o = 0 To 2
        Log (ListaRegistrati(o))
    Next
    
    
    
            
    If   NumeroSchede < Main.NumeroMaxCastelli  Or NumeroSchede  = Main.NumeroMaxCastelli Then
        ListaRegistrati(NumeroSchede) = "1|0|0|0|0|0|0|0|0|0|"
        File.WriteList(File.DirInternal, "GoG/DatiCastello.txt", ListaRegistrati)
        
        
        For i = CLV1.Size -1  To 0 Step -1
            CLV1.RemoveAt(i)
        Next
        
        List1 = File.ReadList(File.DirInternal, "GoG/DatiCastello.txt")
        
      
        For i = 0 To NumeroSchede
            
            If i >= 1 Then
                SoloUnaScheda = False
            Else
                SoloUnaScheda = True
            End If
                        
            Log("Visualizzo Schede "& i &"   CLV1.Size   "&NumeroSchede )
            
            
            ListaRegistrati(i) = List1.Get(i)
            Dim stringArray2() As String = Regex.Split("\|",ListaRegistrati(i))
            
       
                
        
            If Main.Separatore = "PUNTO" Then
                For i=2 To 9
                    stringArray2(i) = stringArray2(i).Replace(",",".")
                Next
            End If
        
        
            
            
            Dim content As String =  stringArray2(2)
            Dim content1 As String =stringArray2(3)
            Dim content2 As String = stringArray2(4)
            Dim content3 As String = stringArray2(5)
        
            Dim contentBis As String = stringArray2(6)
            Dim content1Bis As String = stringArray2(7)
            Dim content2Bis As String = stringArray2(8)
            Dim content3Bis As String = stringArray2(9)
        
            Dim Titolo As String =  $"Castello:  ${stringArray2(1)}"$
            Dim Titolo1 As String = $"Risorse nel castello"$
            Dim Titolo2 As String = $"Risorse da calcolare con gli oggetti"$
    
          
            CLV1.Add(CreateItem(CLV1.AsView.Width, Titolo,Titolo1,Titolo2, Legno,Cibo,Ferro,Mitrhil, content, content1, content2, content3, contentBis, content1Bis, content2Bis, content3Bis), "")
    
      
    
        Next

        Log($"Aggiungo una scheda! "$)
        
    
        Log("Fine Add")
        For o = 0 To 2
            Log (ListaRegistrati(o))
        Next
    Else
    
                Log($"Raggiunto numero massimo di schede"$)
    End If
End Sub
 

udg

Expert
Licensed User
Ciao, in effetti non mi è molto chiaro.
If NumeroSchede < Main.NumeroMaxCastelli Or NumeroSchede = Main.NumeroMaxCastelli Then
corrisponde al più semplice
If NumeroSchede < = Main.NumeroMaxCastelli Then

Per svuotare la CLV, invece del FOR loop puoi semplicemente scrivere CLV1.Clear

Poi, rileggendo la lista da disco, invece di basarti su NumeroSchede, perchè non utilizzi la Size della lista appena letta?

Se capisco le tue intenzioni:
- ammesso non si sia raggiunto il limiite, aggiungi un elemento in coda e salvi sul disco. poi rileggi in memoria
 

LucaMs

Expert
Licensed User
Un suggerimento per i prossimi tuoi sw: usa dei database o più semplicemente dei Type per rappresentare un "oggetto" (un elemento del tuo sw), come potrebbe essere la scheda (intesa come dati) o un "castello" (chissà che è, hehehe)
 

LucaMs

Expert
Licensed User
niente. credo che sia proprio in problema di estrazione e visualizzazione
Visto che dici che devi uscire e rientrare nell'activity, è evidente che da lì ricarichi tutta la CLV.

Però non è normale che tu non veda il nuovo item appena creato ed aggiunto (eh, so che lo sai, per questo poni la domanda :D ma senza avere tutto il codice...!).

Prova a seguire il flusso in modalità debug, eseguendo riga per riga (tasto F8 dopo aver messo in pausa l'app).
 

GIS

Well-Known Member
Licensed User
Visto che dici che devi uscire e rientrare nell'activity, è evidente che da lì ricarichi tutta la CLV.

Però non è normale che tu non veda il nuovo item appena creato ed aggiunto (eh, so che lo sai, per questo poni la domanda :D ma senza avere tutto il codice...!).

Prova a seguire il flusso in modalità debug, eseguendo riga per riga (tasto F8 dopo aver messo in pausa l'app).
F8 non mi ricordo mai che esiste.... Allora assurdo. Praticamente entra nel ciclo for i = o NumeroSchede arriva fino in fondo a clv1.add quando incontro return p al posto di rimanere nel ciclo for mi esce e riprende qui Log($"Aggiungo una scheda! "$). Perciò ovvio che anche se aggiungo più schede lui ne visualizza solo una... Nel ciclo for fa solo un giro poi esce. Spiegazioni?
 

GIS

Well-Known Member
Licensed User
lo rimetto con le modifiche ela sub creaitem

B4X:
Sub AddCastello_Click
            
    Log("aggiungi. Schede totali "& CLV1.Size &" n. max castelli "&Main.NumeroMaxCastelli)
            
    NumeroSchede = CLV1.Size
    
    Log("inizio ADD")
    For o = 0 To 2
        Log (ListaRegistrati(o))
    Next
    
    
    
            
    If   NumeroSchede < Main.NumeroMaxCastelli  Or NumeroSchede  = Main.NumeroMaxCastelli Then
        ListaRegistrati(NumeroSchede) = "1|0|0|0|0|0|0|0|0|0|"
        File.WriteList(File.DirInternal, "GoG/DatiCastello.txt", ListaRegistrati)
        
        CLV1.Clear
        
    List1 = File.ReadList(File.DirInternal, "GoG/DatiCastello.txt")
        
        
    For i = 0 To Main.NumeroMaxCastelli
                
                        
    If i >= 1 Then
        SoloUnaScheda = False
    Else
        SoloUnaScheda = True
    End If
                
                
    ListaRegistrati(i) = List1.Get(i)
    Dim stringArray2() As String = Regex.Split("\|",ListaRegistrati(i))
                
    If stringArray2(0) = "1" Then
                    
        If Main.Separatore = "PUNTO" Then
            For i=2 To 9
                stringArray2(i) = stringArray2(i).Replace(",",".")
            Next
        End If
        
            
            
            Dim content As String =  stringArray2(2)
            Dim content1 As String =stringArray2(3)
            Dim content2 As String = stringArray2(4)
            Dim content3 As String = stringArray2(5)
        
            Dim contentBis As String = stringArray2(6)
            Dim content1Bis As String = stringArray2(7)
            Dim content2Bis As String = stringArray2(8)
            Dim content3Bis As String = stringArray2(9)
        
            Dim Titolo As String =  $"Castello:  ${stringArray2(1)}"$
            Dim Titolo1 As String = $"Risorse nel castello"$
            Dim Titolo2 As String = $"Risorse da calcolare con gli oggetti"$
    
        
            CLV1.Add(CreateItem(CLV1.AsView.Width, Titolo,Titolo1,Titolo2, Legno,Cibo,Ferro,Mitrhil, content, content1, content2, content3, contentBis, content1Bis, content2Bis, content3Bis), "")
            
        End If
    
        Next

        Log($"Aggiungo una scheda! "$)
        

    
        Log("Fine Add")
        For o = 0 To 2
            Log (ListaRegistrati(o))
        Next
    Else
    
                Log($"Raggiunto numero massimo di schede"$)
    End If
End Sub

B4X:
Private Sub CreateItem(Width As Int, Title As String, Title1 As String, Title2 As String,Image As String,Image1 As String,Image2 As String,Image3 As String, Content As String, Content1 As String, Content2 As String, Content3 As String, ContentBis As String, Content1Bis As String, Content2Bis As String, Content3Bis As String) As Panel
    Dim p As B4XView = xui.CreatePanel("")
    Dim height As Int = 280dip
    If GetDeviceLayoutValues.ApproximateScreenSize < 4.5 Then height = 310dip
    p.SetLayoutAnimated(0, 0, 0, Width, height)
    p.LoadLayout("Card1")
    
    lblTitle.Text = Title
    lblTitle1.Text = Title1
    lblTitle2.Text = Title2
    
    lblContent.Text = Content
    lblContent1.Text = Content1
    lblContent2.Text = Content2
    lblContent3.Text = Content3
    
    lblContentBis.Text = ContentBis
    lblContent1Bis.Text = Content1Bis
    lblContent2Bis.Text = Content2Bis
    lblContent3Bis.Text = Content3Bis
    
    'SetColorStateList(lblAction1, xui.Color_LightGray, lblAction1.TextColor)
    'SetColorStateList(lblAction2, xui.Color_LightGray, lblAction2.TextColor)
    ImageLegno.SetBitmap(xui.LoadBitmapResize(File.DirAssets, Image, ImageLegno.Width, ImageLegno.Height, True))
    ImageCibo.SetBitmap(xui.LoadBitmapResize(File.DirAssets, Image1, ImageCibo.Width, ImageCibo.Height, True))
    ImageFerro.SetBitmap(xui.LoadBitmapResize(File.DirAssets, Image2, ImageFerro.Width, ImageFerro.Height, True))
    ImageMithrill.SetBitmap(xui.LoadBitmapResize(File.DirAssets, Image3, ImageMithrill.Width, ImageMithrill.Height, True))
    
    ImageLegnoBis.SetBitmap(xui.LoadBitmapResize(File.DirAssets, Image, ImageLegnoBis.Width, ImageLegnoBis.Height, True))
    ImageCiboBis.SetBitmap(xui.LoadBitmapResize(File.DirAssets, Image1, ImageCiboBis.Width, ImageCiboBis.Height, True))
    ImageFerroBis.SetBitmap(xui.LoadBitmapResize(File.DirAssets, Image2, ImageFerroBis.Width, ImageFerroBis.Height, True))
    ImageMithrillBis.SetBitmap(xui.LoadBitmapResize(File.DirAssets, Image3, ImageMithrillBis.Width, ImageMithrillBis.Height, True))
    
    myImmagine.Initialize(File.DirAssets,"Cestino.png")
    Elimina.SetBackgroundImage(myImmagine)
    
    Log(SoloUnaScheda)
    
    
    
    If SoloUnaScheda = True Then
        
                Elimina.Visible = False
    Else
    
                Elimina.Visible = True
                        
    End If
    
    Return p
End Sub
 

LucaMs

Expert
Licensed User
A occhio ho capito... ma non me va de spreme tantissimo i miei due unici e vecchi neuroni :D

Tu metti questo all'interno della routine che va ad aggiungere un Item - pressione del tasto:
NumeroSchede = CLV1.Size

Poi, sempre nella stessa routine:
List1 = File.ReadList(File.DirInternal, "GoG/DatiCastello.txt")


For i = 0 To NumeroSchede
Quindi, se capisco bene, nella routine aggiungi una riga al file di testo e questa riga dovrebbe andare a riempire un nuovo item creato, ma a quel punto NumeroSchede dovrebbe aumentare di 1.

E' un po' arzigogolato, dovresti avere una routine che crei un nuovo elemento, mentre la tua routine fa un mix tra "aggiungi un elemento" e "aggiungi tutti gli elementi"
 

GIS

Well-Known Member
Licensed User
se guardi nell'ultimo post ho tolto Numero schede con Main.numeroMaxCastelli come ho fatto nelle altre sub per vedere se cosi funzionava. Per la visualizzazione delle schede leggo il primo elemento che se contiene "1" lo visualizzo.... ma niente....
 

GIS

Well-Known Member
Licensed User
poi se i for i=0 to Numeroschede il valore è 1 dovrebbe farmi 0 poi 1 poi uscire perciò leggermi due elementi.... Non l'ho aumentato per l'array parte da 0 mentre lui legge una scheda...perciò a me andava bene cosi... cmq anche se l'ho cambiato con Main.numeromaxcastelli fa la stessa cosa. nel entra ciclo for una volta sola e il valore di Main.numeromaxcastelli e di 2 e quello è un valore che non cambio mai in tutto il programma
 

LucaMs

Expert
Licensed User
se guardi nell'ultimo post ho tolto Numero schede con Main.numeroMaxCastelli come ho fatto nelle altre sub per vedere se cosi funzionava. Per la visualizzazione delle schede leggo il primo elemento che se contiene "1" lo visualizzo.... ma niente....
Beh, ovviamente non conosco le variabili - come Main.numeroMaxCastelli.

Se crei un nuovo elemento sw, diciamo un nuovo record, quello che poi vai a scrivere nel file di testo, usa due routine distinte:

Sub NuovoElemento(parametri vari)
' qui vai ad aggiungerlo al file di testo
NuovoItem(parametri vari)
End Sub

Sub NuovoItem(parametri)
clv.Add(CreateItem(...

Divide et impera (fingo di essere colto :D)


In questo modo sarà più facile il debugging.
 

LucaMs

Expert
Licensed User
poi se i for i=0 to Numeroschede il valore è 1 dovrebbe farmi 0 poi 1 poi uscire perciò leggermi due elementi.... Non l'ho aumentato per l'array parte da 0 mentre lui legge una scheda...perciò a me andava bene cosi... cmq anche se l'ho cambiato con Main.numeromaxcastelli fa la stessa cosa. nel entra ciclo for una volta sola e il valore di Main.numeromaxcastelli e di 2 e quello è un valore che non cambio mai in tutto il programma
Me so' perso, ma se ti serve, come mi pare di capire, oltre alle due routine di cui al mio post precedente, usa una routine per la modifica di un elemento della CLV

Sub ModificaItem(dati che vuoi)
...
 

LucaMs

Expert
Licensed User
cosa intendi per sw dai che imparo qualcosa..... che vuol dire?
elemento software, non c'è da imparare, ho usato questo modo per riferimi a quello che suppongo essere un singolo dato "composto" del tuo sw, cioè la riga che vai a scrivere nel file di testo che, alla fine, mi pare di capire che sia appunto un elenco di "record", cioè ogni riga di testo rappresenta un tuo oggetto che vai a visualizzare nella CLV.

Per questo ti consigliavo una tabella di db oppure di creare un Type nel tuo progetto, Type che rappresenterebbe appunto "una riga" del tuo file di testo, un elemento del tuo sw.

Faccio un esempio stupidotto al volo:

B4X:
Type tPersona(Nome As String, Cognome As String)
Private lstPersone As List

...
lstPersone.Inizialize

'aggiungo una Persona alla lista
Sub AddPersona(Nome As String, Cognome As String)
   Dim NuovaPersona As tPersona
   NuovaPersona.Initialize
   NuovaPersona.Nome = Nome
   NuovaPersona.Cognome = Cognome
   lstPersone.Add(NuovaPersona)
   ' Aggiungo alla CLV
   clvPersone.Add(CreaItem(NuovaPersona, ...
End Sub
Poi avrò una routine per scrivere/leggere tutte le persone da file.

Nota che così la lstPersone puoi anche ordinarla secondo uno dei campi che compongono il tPersona, a tua scelta, in base al Nome o al Cognome, in questo caso.
 

GIS

Well-Known Member
Licensed User
grazie per la spiegazione ma non sto qui a modificare tutta l'App. L'esempio sicuramente è comodo ma dovrei imparare per capire e il problema che mi manca il tempo. Ho risolto il problema alla radice. Ho creato una activity di rimbalzo in questo modo funzione.... cmq ho creato una sub AggiungiScheda anche se per me non aveva molto senso per 4 linee di codice. Praticamente dopo avere aggiunto la scheda schiudo l'activity e passo ad un'altra dove la chiudo subito e richiamo l'activity precedente...
 
Top