Italian horizontalscrollview: mostra sempre la barra di scorrimento

udg

Expert
Licensed User
Longtime User
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!)

Mi sembrava di ricordare che se il panel contenitore aveva un suo Touch, questi consumava l'evento e quindi nelle view contenute non arrivava nulla.
Per provarlo, insieme all'idea del Layout di cui sopra, ho imbastito un pessimo test (che però funziona..eheh).
Come vedete ciascuno dei due pannelli principali contiene un pannello bianco. Se anche metto in ditino sui pannelli bianchi, il touch arriva comunque al pannello contenitore.

In questo test abbiamo il primo pannello (violetto) visibile ed il secondo alla sua destra (quindi ci si aspetta un primo swipe verso sinistra). In un caso "reale" dovremmo avere 3 pannelli (sx, centro, dx).

Nel codice ho abbozzato l'idea di determinare la direzione di spostamento, ma non l'ho utilizzata nel test. Qui mi premeva solo avere due pannelli che si spostavano insieme in funzione del touch su quello inizialmente visibile e che "fissassero" la nuova posizione al raggiungimento di una determinata soglia (nell'esempio, quando il secondo pannello arriva al 20% dello schermo, contato dal margine sx).

Niente Gesture, niente HorizontalScroll, niente SlidingPanels. Solo due pannellini ed il loro touch.. la pigrizia vince sempre!
 

Attachments

  • testslides.zip
    8.3 KB · Views: 133

LucaMs

Expert
Licensed User
Longtime User
Mi sembrava di ricordare che se il panel contenitore aveva un suo Touch, questi consumava l'evento e quindi nelle view contenute non arrivava nulla.
Per provarlo, insieme all'idea del Layout di cui sopra, ho imbastito un pessimo test (che però funziona..eheh).
Come vedete ciascuno dei due pannelli principali contiene un pannello bianco. Se anche metto in ditino sui pannelli bianchi, il touch arriva comunque al pannello contenitore.

In questo test abbiamo il primo pannello (violetto) visibile ed il secondo alla sua destra (quindi ci si aspetta un primo swipe verso sinistra). In un caso "reale" dovremmo avere 3 pannelli (sx, centro, dx).

Nel codice ho abbozzato l'idea di determinare la direzione di spostamento, ma non l'ho utilizzata nel test. Qui mi premeva solo avere due pannelli che si spostavano insieme in funzione del touch su quello inizialmente visibile e che "fissassero" la nuova posizione al raggiungimento di una determinata soglia (nell'esempio, quando il secondo pannello arriva al 20% dello schermo, contato dal margine sx).

Niente Gesture, niente HorizontalScroll, niente SlidingPanels. Solo due pannellini ed il loro touch.. la pigrizia vince sempre!


Provo a leggere, perché sicuramente non posso caricare il progetto (se Erel rilascia la versione che ingloba anche codice Java, giuro che aggiorno :))

Riletto: ovviamente, un conto è vedere, altro è capire una descrizione.
I pannelli bianchi coprono i pannelli contententi le view? Insomma, sono bianchi ma sono quelli che saranno invisibili?
Aggiungi qualche button, verifica la funzionalità globale.
Poi in qualche modo tenterò di ricostruire il tutto per il mio povero 3.0.
 

udg

Expert
Licensed User
Longtime User
Famo prima così
Sub Process_Globals
'These global variables will be declared once when the application starts.
'These variables can be accessed from all modules.
End Sub

Sub Globals
'These global variables will be redeclared each time the activity is created.
'These variables can only be accessed from this module.
Dim p1,p2 As Panel
Dim startx,starty As Int
End Sub

Sub Activity_Create(FirstTime As Boolean)
'Do not forget to load the layout file created with the visual designer. For example:
'Activity.LoadLayout("Layout1")
p1.Initialize("ab")
Activity.AddView(p1,0dip,0dip,100%x,100%y)
p1.LoadLayout("lyt1")
p2.Initialize("ab")
Activity.AddView(p2,100%x,0dip,100%x,100%y)
p2.LoadLayout("lyt2")
startx=0
starty=0
End Sub

Sub Activity_Resume

End Sub

Sub Activity_Pause (UserClosed As Boolean)

End Sub

Sub ab_Touch(Action As Int, x As Float, y As Float)
Dim p As Panel
p = Sender
Dim x1,y1 As Int
x1 = x
y1 = y
Select Action
Case p.ACTION_DOWN
startx = x1
starty = y1
Case p.ACTION_MOVE
' se serve, determina direzione spostamento
Dim direct As Byte
If Abs(x1-startx) > Abs(y1-starty) Then
If x1>startx Then direct=0 Else direct=1 'right or left
Else
If y1>starty Then direct=2 Else direct=3 'down or up
End If
If Abs(x1-startx)> 2%x Then
p1.Left=p1.Left+(x1-startx)
p2.Left=p2.Left+(x1-startx)
End If
Case p.ACTION_UP
If p2.Left < 20%x Then
p1.Left=-100%x
p2.Left=0dip
Else
p1.Left=0dip
p2.Left=100%x+1dip
End If
End Select
End Sub
Poi crea due layout, ciascuno formato da un panel colorato che occupi tutta l'activity ed un secondo panel più piccolo al suo interno.
Se all'interno del panel colorato metti un button, allora è quest'ultimo a rubare il tocco, prendedolo per un click; quindi direi che dipende dal contenuto dei panel se questa idea può essere valida o meno.

ps: anch'io non vedo l'ora che B4A possa inglobare codice java direttamente..
 
Last edited:

LucaMs

Expert
Licensed User
Longtime User
Famo prima così

Poi crea due layout, ciascuno formato da un panel colorato che occupi tutta l'activity ed un secondo panel più piccolo al suo interno.
Se all'interno del panel colorato metti un button, allora è quest'ultimo a rubare il tocco, prendedolo per un click; quindi direi che dipende dal contenuto dei panel se questa idea può essere valida o meno.

ps: anch'io non vedo l'ora che B4A possa inglobare codice java direttamente..

Provo (tanto non riesco a fare niente di intelligente, oggi!).

Ma alla fine hai 2 tris di pannelli così o sbaglio?

Cioè, p1 (panel) carica un layout che contiene due pannelli, uno nell'altro; p2 lo stesso.
 

LucaMs

Expert
Licensed User
Longtime User
Puoi risparmiare il secondo layout lyt2:
B4X:
p2.Initialize("ab")
Activity.AddView(p2,100%x,0dip,100%x,100%y)
p2.LoadLayout("lyt1")
Dim p3 As Panel = p2.GetView(0)
p3.Color = Colors.Green
 

LucaMs

Expert
Licensed User
Longtime User
Diciamo che lo scorrimento con la comparsa del secondo pannello funziona, ma rimane il problema principale (principale dal mio punto di vista):
le view interne al pannello che dovrà scorrere (che poi sono entrambi i pannelli) devono essere attive, ovvero reagire ai loro click, ma devono anche NON reagire quando tu vuoi scorrere i pannelli.

Penso che per questo sia necessario quanto dicevo (e non sono nemmeno certissimo che sia sufficiente!) ovvero un pannello trasparente sul pannello che contiene le view e l'uso della libreria Gesture Detector che "dovrebbe" consentire di gestire lo scorrimento intercettando il Gesture del pannello trasparente.

Il progetto allegato è la tua idea con l'aggiunta di due button: uno nel pannello colorato, uno nel pannello bianco. Entrambi i button reagiscono al click e non consentono lo scorrimento.
 

Attachments

  • udg pannelli.zip
    13.2 KB · Views: 151

udg

Expert
Licensed User
Longtime User
È ciò che dicevo. Questa idea funziona se i pannelli scorrevoli contengono view che non necessitano di eventi click o touch.
Sempre limitatamente al movimento, un'altra soluzione è quella delle DraggableView, la stessa che ho utilizzato nel gioco del 15, ma è abbastanza complessa quindinnon so se ne valga la pena.
A proposito del gioco, da oggi si aprirà la caccia al leader della classifica 2014 con la pubblicazione della nuova versione. Preparati..eheh
 

LucaMs

Expert
Licensed User
Longtime User
È ciò che dicevo. Questa idea funziona se i pannelli scorrevoli contengono view che non necessitano di eventi click o touch.
Sempre limitatamente al movimento, un'altra soluzione è quella delle DraggableView, la stessa che ho utilizzato nel gioco del 15, ma è abbastanza complessa quindinnon so se ne valga la pena.
A proposito del gioco, da oggi si aprirà la caccia al leader della classifica 2014 con la pubblicazione della nuova versione. Preparati..eheh


Azz, si è aperta la stagione della caccia!

Beh, corro ancora molto veloce (eh, mi reggo a malapena in piedi, hehehe)

Sto "studiando" la Gesture Detect proprio in questo momento (prima di prendere sonno per la... notte!)
 

LucaMs

Expert
Licensed User
Longtime User
Ma de che!

Anche con la Gesture D., almeno dalle prime prove, non va. Il pannello trasparente non consente alle view sottostanti di ricevere "tocchi"
 

udg

Expert
Licensed User
Longtime User
Per avere contemporaneamente sia lo scrolling orizzontale che i click sulle view devi necessariamente ricadere sulle stesse funzionalità della HorizontalScrollView..e a quel punto tanto vale usare l'originale! Magari si potrebbe intercettare l'evento OnStatusChanged (o come si chiama) e testare lì dentro la percentuale di copertura dello screen da parte del pannello che si sta spostando.
Il bello di B4A è che la stessa cosa si può fare in tanti modi.
Il brutto di B4A è dover scegliere il modo "giusto" per l'occasione..eheh
 

luciano deri

Active Member
Licensed User
Longtime User
Per avere contemporaneamente sia lo scrolling orizzontale che i click sulle view devi necessariamente ricadere sulle stesse funzionalità della HorizontalScrollView..e a quel punto tanto vale usare l'originale! Magari si potrebbe intercettare l'evento OnStatusChanged (o come si chiama) e testare lì dentro la percentuale di copertura dello screen da parte del pannello che si sta spostando.
Il bello di B4A è che la stessa cosa si può fare in tanti modi.
Il brutto di B4A è dover scegliere il modo "giusto" per l'occasione..eheh
Intanto grazie per la disponibilità e cura con cui avete analizzato la mia questione. Il realtà se la con la scroll si intercettasse correttamente l'UP non si sarebbero problemi, l'OnStatusChanged a quale oggetto è associato?
 

udg

Expert
Licensed User
Longtime User
Ciao Luciano.
Scusa, ma il nome esatto è ScrollChanged(Position As Int).
Dovrei avere un vecchio progetto che utilizzava la HSV. Controllo e ti faccio sapere se ricordo bene e come gestivo la sequenza Down-Move-Up.

Edit:
ho dato una rapidissima occhiata al codice di cui dicevo. In effetti utilizza una HSV in cui carico dei pannelli. La cosa strana, dico così perchè è stata veramente un'occhiata fugace prima di prepararmi ad uscire, è che inizializzando la HSV non registro alcun evento, mentre i pannelli gesticono il Touch per capire se vengono cliccati.
Sempre i pannelli hanno anche:
Case P.ACTION_MOVE
Return True

Mentre sono fuori, prova a vedere se può funzionare anche per te:
niente evento su HSV
niente evento sui panel (che sarebbero poi le tue pagine da scorrere)
sì evento su un button o altra view contenuta nei panel

A più tardi.
 
Last edited:

LucaMs

Expert
Licensed User
Longtime User
Fettecchiamientos!

Tutta 'sta fatica e basta usare la HorizontalScrollView normalmente (ho appena provato).
Cioè, funziona quello che intendevo, lo scroll ma anche il click su eventuali Button.

Quindi è solo una questione di calcoli sulle larghezze dei panel aggiunti!

Bon, allora rileggo la domanda del primo post :D
 

luciano deri

Active Member
Licensed User
Longtime User
Fettecchiamientos!

Tutta 'sta fatica e basta usare la HorizontalScrollView normalmente (ho appena provato).
Cioè, funziona quello che intendevo, lo scroll ma anche il click su eventuali Button.

Quindi è solo una questione di calcoli sulle larghezze dei panel aggiunti!

Bon, allora rileggo la domanda del primo post :D
Infatti non ho problemi di scroll e neppure di eventi sui singoli view contenuti nei pannelli, volevo solo riuscire a ricreare quanto fa il desktop di android, ad occhio sembra proprio un HSW, ma con la particolarità che centra le pagine nell'UP
 

LucaMs

Expert
Licensed User
Longtime User
Infatti non ho problemi di scroll e neppure di eventi sui singoli view contenuti nei pannelli, volevo solo riuscire a ricreare quanto fa il desktop di android, ad occhio sembra proprio un HSW, ma con la particolarità che centra le pagine nell'UP

Mooolto tempo fa ci pensai anche io, perché mi piace; inoltre, avrei voluto usarlo per passaare da una Activity ad un'altra, non solo tra pannelli.

Comunque, la soluzione ovviamente c'è, visto che funziona! e quasi certamente si dovrà usare la libreria Gesture Detector insieme alla Hor...

A meno che qualcuno che abbia già fatto prove a sufficienza non intervenga dandoci la giusta dritta, appena posso cercherò di capire bene come funzionano i metodi di quella llibreria.
 

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
Scusate se torno sull'argomento. Ho utilizzato lo stesso metodo per valorizzare il contenuto di un database, ma in questo modo devo dichiarare un numero finito di pannelli quante sono le righe lette dal database, con conseguente rallentamento nell'apertura del programma.
B4X:
strquery = "SELECT inventario.id, inventario.codrag, articoli.codart, articoli.descrizione, inventario.qta, inventario.flg_elimina FROM inventario LEFT JOIN articoli ON inventario.codart = articoli.codart WHERE inventario.codrag ='" & etcodrag.Text & "' ORDER BY inventario.id DESC "
    dbCursor = Main.dbSql.ExecQuery(strquery)
    Dim pnl(dbCursor.RowCount) As Panel
    For i = 0 To dbCursor.RowCount - 1
    DoEvents
        dbCursor.position = i
       
        'Dim pnl As Panel
        pnl(i).Initialize("Pelenco")
        swelenco.Panel.AddView(pnl(i), 0, i * CH, 100%x, PH)
       
        pnl(i).LoadLayout("LRigaRilInve")
        pnl(i).Tag = dbCursor.GetInt("inventario.id")
        lbcodice.Text = dbCursor.GetString("articoli.codart")
        lbdesc.Text = dbCursor.GetString("articoli.descrizione")
        lbqta.Text = dbCursor.GetString("inventario.qta")
        If lbqta.Text = "" OR lbqta.Text = " " Then
            lbqta.Text = 0
        End If       
        qta = lbqta.Text
        totqta = totqta + qta   
        flg_elimina = 0
        flg_elimina = dbCursor.Getint("inventario.flg_elimina")
        If MultiMode AND  dbCursor.Getint("inventario.flg_elimina") = 1 Then
            ColoreSelezioneMultimode
        Else
            ColoreNonSelezione
        End If   
        pline.Width = pnl(i).Width   
    Next
    swelenco.Panel.Height = dbCursor.RowCount*PH
 

LucaMs

Expert
Licensed User
Longtime User
Scusate se torno sull'argomento. Ho utilizzato lo stesso metodo per valorizzare il contenuto di un database, ma in questo modo devo dichiarare un numero finito di pannelli quante sono le righe lette dal database, con conseguente rallentamento nell'apertura del programma.


Non ho letto il codice, solo la domanda (affermazione, direi) e senza approndire molto (come dire: "metto le mani avanti nel caso in cui dicessi una ca...stroneria :p).

Soluzione complicatuccia ma efficiente e direi corretta: caricare un record (che suppongo corrisponda ad un pannello) solo quando il relativo pannello sia visibile (anche parzialmente).
 

luciano deri

Active Member
Licensed User
Longtime User
La precedente versione della stessa sub, pnl non era un vettore, ma un unica variabile che veniva reinizializzata ad ogni next, incorrendo nello stesso errore che mi avete segnalato segnato in cui avevo un unica variabile tab ma valorizzato con tanti Tag. In realtà non avevo riscontrato nessun problema operativo. Con questo nuovo metodo, formalmente sarà anche migliore, però è più lento perchè ho molta più memoria usata in base alle dimensione del vettore
Dim pnl(dbCursor.RowCount) AsPanel.
 
Top