Italian horizontalscrollview: mostra sempre la barra di scorrimento

luciano deri

Active Member
Licensed User
Longtime User
Salve. Ho usato un horizontalscrollview per mostrare più pagine di una scheda informativa, e funziona tutto bene, mi piacerebbe però che si vedesse sempre la barra di scorrimento in modo da far capire all'utente se ci sono ancora pagine da sfogliare (i riquadri sul desktop del samsung sono fantastici, ma mi accontento anche di qualcosa più semplice). Come si può fare? C'è una semplice proprietà dalla scrollview o devo aggiungere un componente apposito?
Grazie e auguri di buon anno.
 

luciano deri

Active Member
Licensed User
Longtime User
Altro problema relativo allo stesso progetto. Vorrei evitare le scroll si fermi visualizzando due mezze pagine. Ho dimensionato il panel in modo che occupi tutta la larghezza, e ci sono quasi riuscito con il seguente codice, il problema è che non esegue sempre l'evento PScreen_Touch con ACTION_UP. Il programma intercetta il DOWN e il MOVE, ma non sempre l'UP
B4X:
Sub popola_screen
    nscreen = 0
    HSVdati.Panel.RemoveAllViews
   
    pnl.Initialize("PScreen")
                        'nome pannello, left di inizio, top ,larghezza, altezza
    HSVdati.Panel.AddView(pnl, PnToolBar.Left + 0*PnToolBar.Width, 0, PnToolBar.Width, HSVdati.Height)
    pnl.LoadLayout("LDatiGen")
    pnl.Tag ="LDatiGen"
    nscreen = nscreen + 1
   
    pnl.Initialize("PScreen")
    HSVdati.Panel.AddView(pnl, PnToolBar.Left + 1*PnToolBar.Width, 0, PnToolBar.Width, HSVdati.Height)
    pnl.LoadLayout("LSinonimi")
    pnl.Tag ="LSinonimi"
    nscreen = nscreen + 1
   
    HSVdati.Panel.Width = nscreen * pnl.Width
   
End Sub
Sub PScreen_Touch (Action As Int, x As Float, y As Float)
    pnl = Sender 'forse non serve
    Dim resto As Int
    Dim position As Int
    Select Action
        Case Activity.ACTION_DOWN
            startX = x
            startY = y
        Case Activity.ACTION_UP
           ' If Abs(y - startY) > 20%y Then Return
            position = HSVdati.ScrollPosition
            nscreen = position / pnl.Width
            resto = HSVdati.ScrollPosition Mod pnl.Width
            If resto > 0 Then
                If resto > 50%x  Then
                    HSVdati.ScrollPosition = pnl.Width * (nscreen + 1)
                Else   
                    HSVdati.ScrollPosition = pnl.Width * (nscreen)
                End If
            End If   
    End Select
End Sub
Grazie e saluti
 

luciano deri

Active Member
Licensed User
Longtime User
PnToolBar è un pannello di intestazione alla scheda, in questo caso vale 100%x ma non è detto che riduca questa zona nella mia maschera, ho fatto per generalizzare l'istruzione, ancora meglio sarebbe. Così posso copiarla per aggiungere infiniti pannelli al mio scroll

HSVdati.Panel.AddView(pnl, PnToolBar.Left + nscreen*PnToolBar.Width, 0, PnToolBar.Width, HSVdati.Height).
nscreen = nscreen + 1
 

luciano deri

Active Member
Licensed User
Longtime User
Sembra un problema di velocità. Se scorro lentamente e soprattutto sono lento nel rilasciare il display esegue tutti e tre , altrimenti prende solo il MOVE, o la massimo l'UP e il MOVE.
 

luciano deri

Active Member
Licensed User
Longtime User
E' un problema grosso. Action_Up lo esegue solo in caso di click, se fai scorrimento non lo esegue mai. In oltre c'è Action = 3 che non è sotto definito che viene eseguito all'inizio del move. Quindi mi manca l'evento di fine move. :mad:
 

luciano deri

Active Member
Licensed User
Longtime User
Sbaglio o c'è un problemino anche con il pnl? Dovrebbero essere due, uno col Tag LDatiGen e l'altro col Tag LSinonimi; quindi dovresti dargli due nomi diversi, tipo pnlDatiGen e pnlSinonimi
Non lo so, non sono espertissimo ma mi sembra che negli esempi dello ScrollView in cui viene usato per visualizzare tanti record di una tabella sqlite abbiano sempre lo stesso nome, in questo modo l'evento che si attiva al click o al touch è sempre lo stesso.

Tornando al problema di fondo,probabilmente sto utilizzando il metodo o l'oggetto sbagliato. In pratica voglio realizzare un funzionamento analogo al desktop di android in cui facendo scroll sulle pagine se il movimento non è almeno la metà dell'asse x resti centrato nella pagina attuale oppure si centra automaticamente su quella successiva. Se osservi l'automatismo si innesca quando alzo il dito, ma nel mio caso l'UP lo fa solo dopo un DOWN e mai dopo un MOVE, quindi diventa quasi un CLICK
 

udg

Expert
Licensed User
Longtime User
Ciao Luciano,

in sostanza vuoi realizzare uno scorrimento orizzontale di pagine, ma con un check sulla % di movimento in modo da annullarlo se non supera quel valore?
Prova a partire da questo thread ed eventualmente leggi anche degli sliding panels citati in uno dei primi post.

Riguardo alla giusta osservazione di LucaMs in merito al riutilizzo di pnl con 2 layout: una cosa è il nome comune (PScreen) da dare all'evento in fase di inizializzazione (in modo da centralizzare le risposte dei vari panel) e l'altra è il nome del pannello (pnl).

Ti lascio alla tua lettura, ma ricorda di farci sapere come procede
 

luciano deri

Active Member
Licensed User
Longtime User
Ciao Luciano,

in sostanza vuoi realizzare uno scorrimento orizzontale di pagine, ma con un check sulla % di movimento in modo da annullarlo se non supera quel valore?
Prova a partire da questo thread ed eventualmente leggi anche degli sliding panels citati in uno dei primi post.

Riguardo alla giusta osservazione di LucaMs in merito al riutilizzo di pnl con 2 layout: una cosa è il nome comune (PScreen) da dare all'evento in fase di inizializzazione (in modo da centralizzare le risposte dei vari panel) e l'altra è il nome del pannello (pnl).

Ti lascio alla tua lettura, ma ricorda di farci sapere come procede
Ok, la Classe SlidingPanels è interessante, tra l'altro sembra che nei suoi esempi l'evento UP viene esegui sempre correttamente. Negli esempi dichiarano un array di pannelli in modo da usare l'indice per diversificare il pannello per ogni layout. Facendo come ho fatto io è solo brutto oppure possono esserci effettivi problemi operativi? Mantenendo lo stesso nome posso sfruttare il tag per sapere quale pannello ho cliccato. Altrimenti come faccio a sapere quale pnl(n).tag leggere?
B4X:
sub pnl_Click
       pnl = Sender
      Log("Tab cliccato " pnl.tag")
end sub
Saluti e Grazie.
 
Last edited:

LucaMs

Expert
Licensed User
Longtime User
Non lo so, non sono espertissimo ma mi sembra che negli esempi dello ScrollView in cui viene usato per visualizzare tanti record di una tabella sqlite abbiano sempre lo stesso nome, in questo modo l'evento che si attiva al click o al touch è sempre lo stesso.

Tornando al problema di fondo,probabilmente sto utilizzando il metodo o l'oggetto sbagliato. In pratica voglio realizzare un funzionamento analogo al desktop di android in cui facendo scroll sulle pagine se il movimento non è almeno la metà dell'asse x resti centrato nella pagina attuale oppure si centra automaticamente su quella successiva. Se osservi l'automatismo si innesca quando alzo il dito, ma nel mio caso l'UP lo fa solo dopo un DOWN e mai dopo un MOVE, quindi diventa quasi un CLICK


Affinché due view qualunque intercettino il medesimo evento, devi inizializzarle con lo stesso nome evento.
Questo puoi farlo nel Designer oppure da codice.

Per esempio:
pnlQualcosa.Initialize("NomeEvento")
pnlDiverso.Initialize("NomeEvento")

Poi nell'evento (click, ad esempio) usi il Sender che non sapevi se usare o no:

Sub NomeEvento_Click
Dim pnlGenerico As Panel = Sender
...
End Sub

A quel punto, il pnlGenerico è come se diventasse il pannello stesso che ha generato l'evento, quindi pnlQualcosa se hai fatto click su questo, oppure pnlDiverso.
Dico è come se diventasse perché in realtà sia pnlGenerico che pnlQualcosa (se hai clickato su questo) PUNTANO allo stesso oggetto in memoria.

Il discorso di Android, scorrimento, etc.

A parte la faccenda della metà del pannello, che ho capito, il problema è che se poi metti, come è ovvio, delle view sui pannelli, per far scorrere il pannello dovrai "trascinare" proprio il pannello; cioè se tocchi una view e trascini il dito su quella con l'intenzione di trascinare tutto il pannello, non ti funzionerà.

Come risolvere... dato che non l'ho ancora fatto, lascio il piacere a @udg :D
 

LucaMs

Expert
Licensed User
Longtime User
A parte la faccenda della metà del pannello, che ho capito, il problema è che se poi metti, come è ovvio, delle view sui pannelli, per far scorrere il pannello dovrai "trascinare" proprio il pannello; cioè se tocchi una view e trascini il dito su quella con l'intenzione di trascinare tutto il pannello, non ti funzionerà.

Molto probabilmente dovrai usare un pannello trasparente sopra ogni pannello utile (visibile) e poi sfruttare la libreria Gesture Detector
 

luciano deri

Active Member
Licensed User
Longtime User
Mooolto bene. Quindi nell'esempio basta fare
Molto probabilmente dovrai usare un pannello trasparente sopra ogni pannello utile (visibile) e poi sfruttare la libreria Gesture Detector
Moolto bene, il discorso del nome pannello è chiaro. Per adesso il problema del pannello trasparente lo avevo già messo in conto, Gesture Detector l'ho trovato , c'è un bell'evento onScroll, devo provarlo bene. Il discorso che non esegue anction_UP alla fine dello swipe ti risulta?
E quando action = 3 a che situazione corrisponde?
Altra cosa relativamente ai pannelli, perchè la proprietà enabled non viene ereditata dai child?
 

udg

Expert
Licensed User
Longtime User
Scusate se sono un po' incostante, ma un'occhiata prima o poi ci scappa..eheh

Ok, vedo che la questione nome_evento/nome_pannello è risolta e confermo che va benissimo utilizzare il tag per differenziare il pannello cliccato una volta rilevato il Sender.
La Gesture Detection potrebbe non essere necessaria visto che il pannello ha la sua Touch è strutturata allo steso modo.

Una domanda: quando sposti il pannello corrente a dx o sx (ma prima di rilasciare) vuoi che si veda conteporaneamente anche il nuovo pannello oppure ti basta che se lo spostamento di quello corrente supera un certo valore % solo al rilascio appaia quello che dovrebbe essere alla sua dx o sx in funzione del movimento?
In quest'ultimo caso una furbata potrebbe essere quella di fare a meno anche della HorizontalScrollView e sfruttare il panel.loadLayout! In pratica avresti un solo pannello del quale gestisci l'eveto touch. Quando rilevi l'UP verifichi se si è spostato a dx o sx (e se ha superato il x%) e di conseguenza lo riposizioni centrato con il nuovo layout.

Se hai difficoltà (con una qualunque delle soluzioni) lascia un commento che tra un po' ritorno... UHHHHHHHHHHHHH (per questa, chiedi a LucaMs eheh)
 

LucaMs

Expert
Licensed User
Longtime User
Scusate se sono un po' incostante, ma un'occhiata prima o poi ci scappa..eheh

Ok, vedo che la questione nome_evento/nome_pannello è risolta e confermo che va benissimo utilizzare il tag per differenziare il pannello cliccato una volta rilevato il Sender.
La Gesture Detection potrebbe non essere necessaria visto che il pannello ha la sua Touch è strutturata allo steso modo.

Una domanda: quando sposti il pannello corrente a dx o sx (ma prima di rilasciare) vuoi che si veda conteporaneamente anche il nuovo pannello oppure ti basta che se lo spostamento di quello corrente supera un certo valore % solo al rilascio appaia quello che dovrebbe essere alla sua dx o sx in funzione del movimento?
In quest'ultimo caso una furbata potrebbe essere quella di fare a meno anche della HorizontalScrollView e sfruttare il panel.loadLayout! In pratica avresti un solo pannello del quale gestisci l'eveto touch. Quando rilevi l'UP verifichi se si è spostato a dx o sx (e se ha superato il x%) e di conseguenza lo riposizioni centrato con il nuovo layout.

Se hai difficoltà (con una qualunque delle soluzioni) lascia un commento che tra un po' ritorno... UHHHHHHHHHHHHH (per questa, chiedi a LucaMs eheh)



HHHUUUUHHHHH UDG

(trattasi di fantasma! quindi va salutato così).

La Gesture è necessaria, a meno che, come dicevo, non metti il ditINO solo sul panel, perché se lo metti su una view contenuta nel panel, non ottieni lo scorrimento, ma l'evenuale evento di quella view (miiii cacofonico sono!)

Immagino che Luciano voglia proprio vedere il pannello "entrante", fa un altro effetto.

Per le altre domande, dovrei provare, come sempre, ma, sigh, non ho tempo. Vorrà dire che approfitterò smodatamente delle soluzioni trovate da Luciano, hehehe.
 
Top