Italian [B4A-B4J] Impostare la proprietà Top di una CustomListView caricata all'interno di un pane/panel

Elric

Well-Known Member
Licensed User
Ho 3 layout:
  • quello della MainPage
  • quello del panel/pane (definito come B4XView e che chiamo "pnlSplash") in cui carico un layout in cui c'è la sola CustomListView
  • quello in cui ci sono le view che compongono il singolo item della CustomListView
Il pnlSplash aggiuntivo ha le dimensioni uguali all'intera pagina, in modo che le View che sono nella MainPage sono coperte dal pnlSplash e non possono essere cliccate finché il pnlSpalsh è visibile.

Funziona tutto, ma ho un solo problema.

Mi piacerebbe tanto che la CustomListView fosse centrata verticalmente all'interno del pnlSplash.

Dopo innumerevoli tentativi, sono riuscito ad ottenere:
  • che dopo una frazione di secondo questa si "teleporta" dall'alto al centro ma con un lag.
  • aggiungerla dentro un pnlSplash2 a sua volta aggiunto dentro pnlSplash e impostando la proprietà top di pnlSplash2.
B4X:
Private Sub LoadlayCLV(myPnl As B4XView)
    ' ***********************************************
    ' Here there is an issue to center vertically the CustomListView1:
    ' The code in "Else" makes CustomListView1 lagging, also in Release.
    ' the pnlSplash is added to MainPage by SetpnlSplash sub
    ' ***********************************************
    Dim myynDoppioPnl As Boolean = False ' Variable for DEBUG
    If myynDoppioPnl Then ' If myynDoppioPnl is true then add the CLV not directly to pnlSplash but to another panel within the pnlSplash
        Dim myPnlCLV As B4XView
        myPnlCLV = xui.CreatePanel("myPnlCLV")
        myPnlCLV .Tag = "pnlSplashCLV"
        myPnlCLV.LoadLayout("layCLV")
        FillCLV
        Dim mydblTop As Double
        mydblTop = GetTopToCenterViewInAnotherView(CustomListView1.AsView, pnlParent)
        myPnlCLV.Top = mydblTop
        myPnl.AddView(myPnlCLV, 0, mydblTop, myPnl.Width, myPnl.Height)
    Else                    ' Else myynDoppioPnl is false then add the CLV directly to pnlSplash
        myPnl.LoadLayout("layCLV")
        FillCLV
        Dim myCLV As CustomListView = CustomListView1
        Dim mydblTop As Double
        mydblTop = GetTopToCenterViewInAnotherView(myCLV.AsView, pnlParent)
        myCLV.AsView.SetLayoutAnimated(35, myCLV.AsView.Left, mydblTop, myCLV.AsView.Width, myCLV.AsView.Height)
        ' 30-35 is the minimum value to make moving CustomListView1, otherwise appears with Top value 0
    End If
End Sub
Nessuno dei due è elegante. Il primo è un obbrobrio a vedersi, il secondo non è il massimo dal punto di vista della programmazione.

Qualcuno ha qualche idea?
Grazie!
 

Attachments

  • glbLoading250910.zip
    22.9 KB · Views: 6

LucaMs

Expert
Licensed User
Longtime User
Proverò a dare un'occhiata alla versione B4A, perché in B4J (debug) appare così:

java_hrN0cH3xqp.gif


Un Pane con una B4XLoadingIndicator e una Label ed è questo a scendere dall'alto; la CustomListView?

Se anche in B4A dovesse risultare così, converrà provare varie cosette (eseguire step-by-step, senza avviare il ciclo per il B4XLoadingIndicator, non nascondere...).

(Mi perdo "un po' " con i nomi che hai usato - ad esempio mi pare di vedere che per le "variabili membro delle proprietà" usi il prefisso "yn"; non sarebbe male se avessimo tutti uno "stile", "naming" da seguire, mi pare che qualcuno chiese se ne esistesse uno, ma temo che non si farà mai <-- errore, doppia negazione: "non... mai" = almeno una volta, ma "oggi" si parla... così 😁 :confused:).

Adesso, FORSE, mi è "caduto il gettone"! Non sarà, invece, che usi quel prefisso "yn" per "yes/not", ovvero per variabili booleane? Eh, penso proprio di sì.

P.S. E adesso forse mi è caduto un secondo gettone. Essendo uno splash, con quell'B4XLoadingIndicator, probabilmente vuoi nascondere il caricamento dei dati nella CLV, fino al completamento; ma allora perché la CLV dovrebbe stare nel pannello splash? 😳

-----------------

Una cosa strana, sulla quale si dovrebbe indagare (non riguarda il tuo problema grafico).
Hai:
B4X:
    Do Until cLD.CycleDone
        Sleep(1) ' Tanto vale mettere zero anziché 1.
    Loop
Bene, se chiudi, anzi tenti di chiudere, la B4XMainPage (in realtà il MainForm)... non si chiude finché non si conclude quel loop!
Probabilmente proprio a causa dello Sleep, impostato su un valore talmente basso che non fa scattare l'evento (interno) del click sulla "crocetta" di chiusura.
Anzi, adesso provo con Sleep(100) e lo sapremo "subito"...
confermato.
 
Last edited:
Upvote 0

LucaMs

Expert
Licensed User
Longtime User
E' tutto un po' contorto:

1757554292213.png


1. Non chiamare pnlSplashxxxx una routine (Sub) perché sembra il nome di un Pane(l).
2. Perché anziché creare due routine, pnlSplashTrue e pnlSplashFalse, non ne crei una sola e gli passi un valore booleano, ad esempio:
Sub SetSplashVisible(Visible As Boolean)?
3. Sicuro di dover rimuovere il Pane(l)? Basterebbe nasconderlo. Probabilmente perché lo crei da codice PIU' VOLTE (?)

E' proprio l'aver usato queste variabili booleane - diciamo: di stato - che ti complica la vita:
B4X:
    Private ynVisible As Boolean
    Private ynAdded As Boolean

    Private ynRemoveFromRoot As Boolean
    Private ynProgressBar As Boolean
(ovviamente non la sola loro creazione, ma il loro utilizzo).
 
Upvote 0

Elric

Well-Known Member
Licensed User
Grazie per la risposta.

La gif che hai postato è quello che vorrei evitare e che mi succede se modifico la proprietà Top della CustomListView.

Se invece opto per un secondo pnl (impostando myynDoppioPnl = True in
Private Sub LoadlayCLV) non dovrebbe avvenire ma, come già scritto, mi pare più un accrocchio poco stiloso.

Scopo del progetto allegato
È un progetto (per me) didattico. Lo sto usando per capire come realizzare librerie con dei layout e delle view. Fa parte dello studio e dell'implementazione (lenta) di altri progetti.

Prevede la possibilità per l'utilizzatore della classe/libreria di optare per far apparire un B4XLoadingIndicator e una Label (informazioni sommarie) oppure una CustomListView con una AnotherProgressBar e una Label per ciascuna attività in corso (informazioni dettagliate). La scelta è fatta attraverso il cambio di valore booleano cLD.ProgressBar che, per esigenze di debugging, è nella MainPage alla sub Button1_Click. Nel progetto allegato è impostata true ed è per questo che vedi le progress bar invece del loading indicator.

La rimozione o la tenuta del pnlSplash (da cui le variabili booleane che ritieni creino confusione) fa sempre parte dello studio, per capire se è meglio tenere il pnlSplash costruito o costruirlo di volta in volta. Magari, in progetti complessi, con tante view, una view in meno potrebbe fare comodo. Anche questa è sotto forma di opzione, in questo progetto impostato nella sub Button1_Click.

Nomenclatura
Si, mi sono imposto una convenzione nell'assegnazione dei nomi alle variabili, onde non impazzire in progetti un pelo complessi. Cerco di usare la nomenclatura così detta "camelCase". Le variabili globali hanno un prefisso di tre lettere, preferibilmente consonanti, fatta eccezione per le booleane, che hanno un più semplice "yn" (dovrei usare "bln" o "tf" ma "yn" è per me più intuitivo) mentre per le locali si aggiunge un ulteriore prefisso "my" (che sta per "mio" ma della sub).
Non ho (ancora) adottato una nomenclatura per le sub (da cui l'errore che hai sottolineato).

La "cosa strana del ciclo CycleDone"
Si, è strana e non ci dovrebbe essere.
Il tutto nasce dal fatto che per avere due progress bar che partono insieme ma il progetto attende che entrambe finiscano un Wait for non è sufficiente (vedi https://www.b4x.com/android/forum/threads/b4x-wait-for-multiple-tasks-to-complete.150329/ e, per una sua implementazione pratica, il mio https://www.b4x.com/android/forum/t...d-more-than-one-file-at-the-same-time.168453/).
Ma devo aver implementato male perché senza questo strano ciclo il pnlSplash si nasconde subito. Ma è un problema diverso, che meriterebbe eventualmente un altro thread.

1. Non chiamare pnlSplashxxxx una routine (Sub) perché sembra il nome di un Pane(l).
Si, prima o poi imparerò o utilizzerò una nomenclatura che non mi faccia fare questi errori.

2. Perché anziché creare due routine, pnlSplashTrue e pnlSplashFalse, non ne crei una sola e gli passi un valore booleano, ad esempio:
Sub SetSplashVisible(Visible As Boolean)?
Lo faccio già come chiamata esterna. Internamente alla classe, lo trovo più ordinato, secondo i miei schemi mentali. Che non è detto siano semplici o non confusi.

Come hai fatto a fare le due piccole finestre? :)
 
Upvote 0
Top