Italian list dove gli elementi sono persone

fabio_linate_milano

Member
Licensed User
Longtime User
Salve a tutti

Avrei un problemino ....
allora ...
Se io voglio creare una lista di array nessun problema
per esempio

B4X:
Sub Globals
    'These global variables will be redeclared each time the activity is created.
    'These variables can only be accessed from this module.
   
    Dim elenco As List

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")
   
    elenco.Initialize
    elenco.Add(Array As String("wqeqw", "asas", "cvcvb"))
    elenco.Add(Array As String("fabio", "asasas"))
    elenco.Add(Array As String("pippo", "pluto", "bbbbbbbbbbbbbb"))
    elenco.Add(Array As String("paperino"))

End Sub

Per intenderci è la stessa struttura che si ottiene quando si carica con la loadcsv.
La mia intenzione è quella di fare una cosa più elegante, creare una lista di un tipo definito mediante type.
questo è il mio tentativo:

B4X:
Sub Process_Globals
    'These global variables will be declared once when the application starts.
    'These variables can be accessed from all modules.
   
    Type persona(nome As String, cognome As String)

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 elenco As List
    Dim singolo As persona

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")
   
    elenco.Initialize
    singolo.Initialize
    singolo.nome = "marco"
    singolo.cognome = "marchini"
    elenco.Add(singolo)
    singolo.Initialize
    singolo.nome = "paolino"
    singolo.cognome = "paperino"
    elenco.Add(singolo)
    singolo.Initialize
    singolo.nome = "topino"
    singolo.cognome = "topolino"
    elenco.Add(singolo)


End Sub

Più precisamente ho notato (mi sembra di aver notato/capito) che
elenco.add(singolo)
non aggiunge la struttura singolo (come contenuto) ma un puntatore alla struttura. Quindi quando cambio il contenuto di singolo cambia anche il contenuto dell'elemento della lista elenco.

un saluto
 

LucaMs

Expert
Licensed User
Longtime User
Non ho capito quale sia il tuo "problemino". Mi sembra tutto esatto (ho letto velocemente, però).

Più in generale, dovendo fare una cosa come la tua, io farei in modo non molto diverso (sembra più complicato ma è altrettanto semplice e, soprattutto, più "utile").

1) Creerei una classe, anziché un tipo. Il motivo è la possibilità di effettuare un controllo sui dati inseriti (nel tuo caso solo nome e cognome, ma tu potresti aver bisogno di più "proprietà").

Quindi, invece di Type persona(nome AsString, cognome AsString) io avrò la classe clsPersona.

2) invece di una List userei una Map.
Avendo una mapPersone, se io avessi anche un codice univoco nella classe persona (guarda caso, come in una tabella di database ;)), potrei scrivere:

Dim Persona As clsPersona
Persona.Initialize
Persona.ID = 1
Persona.Nome = "Paolino"
Persona.Cognome = "Paperino"
Persona.TutteLeProprietàCheVoglio (ma con il controllo nelle routine setNome, setCognome,...)
mapPersone.Put(Persona.ID, Persona)

Potrei anche usare il cognome, come indice, ovviamente (ma i cognomi non sono univoci, ovviamente):
Dim Persona As clsPersona
Persona.Initialize
Persona.Nome = "Paolino"
Persona.Cognome = "Paperino"
mapPersone.Put(Persona.Cognome, Persona)

A quel punto, potrò cercare una Persona per ID (o per cognome, nel secondo caso).

Un altro modo sarebbe quello di creare, oltre alla classe Persona, anche una classe Persone, che contenga una List o Map di oggetti Persona e che esponga questa List o Map tramite una proprietà.

Insomma, considera che ogni più piccolo "oggetto" del linguaggio VB.Net (ma non solo) è derivato da una classe! Questo perché poi è tutto più semplice da tenere ordinato e per le modifiche.

In questo mondo Android (in B4A, non in Java) le classi sono moooolto sottovalutate e inutilizzate.
 

LucaMs

Expert
Licensed User
Longtime User
non aggiunge la struttura singolo (come contenuto) ma un puntatore alla struttura. Quindi quando cambio il contenuto di singolo cambia anche il contenuto dell'elemento della lista elenco.

Questo è vero per qualsiasi oggetto, non solo nelle List.

Se crei un oggetto di tipo Persona da una classe, come ho scritto sopra:

Dim Persona1 As clsPersona
...

se poi scrivi:
Dim Persona2 As clsPersona
Persona2 = Persona1

entrambe le variabili, Persona1 e Persona2, punteranno alla stessa zona di memoria, quindi se cambi il "cognome" di uno dei due oggetti, cambierà anche l'altro, perché in realtà modifichi un "campo" di quella zona di memoria alla quale entrambe le variabili puntano.
 

fabio_linate_milano

Member
Licensed User
Longtime User
Salve

grazie per la risposta
Ho provato con le classi e la struttura map ma la sostanza del discorso non cambia
procediamo con ordine
Ho definito una classe come
B4X:
'Class module

Sub Class_Globals
   
    Public id As Byte
    Public nome, cognome As String
   
End Sub

'Initializes the object. You can add parameters to this method if needed.
Public Sub Initialize

End Sub

e un programma chiamante come
B4X:
Sub Globals
    'These global variables will be redeclared each time the activity is created.
    'These variables can only be accessed from this module.
   
    Dim tizio,corrente As clsPersona
    'Dim elenco As List
    Dim rubrica As Map
    Dim i As Byte
    Dim risultato As String

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")
   
    'elenco.Initialize
    rubrica.Initialize
   
    tizio.Initialize
    tizio.Id = 1
    tizio.nome = "paolino"
    tizio.cognome = "paperino"
    'elenco.Add(tizio)
    rubrica.Put(tizio.id, tizio)
   
    tizio.Initialize
    tizio.id = 2
    tizio.nome = "rocky"
    tizio.cognome = "balboa"
    'elenco.Add(tizio)
    rubrica.Put(tizio.id, tizio)
   
    'controllo
'    For i = 0 To elenco.Size - 1
'        corrente = elenco.Get(i)
'        risultato = risultato & corrente.nome & ":" & corrente.cognome & CRLF
'    Next

    For i = 0 To rubrica.Size - 1
        corrente = rubrica.GetValueAt(i)
        risultato = risultato & corrente.id & ":" & corrente.nome & ":" & corrente.cognome & CRLF       
    Next
    Msgbox(risultato, "")
   
End Sub

ho provato prima con la lista elenco (che corrispondono alle parti commentate) e poi con la variabile rubrica di tipo map.
Alla fine (in entrambi i casi) mi ritrovo con una struttura (list oppure map) con due elementi che sono uguali e corrispondono all'ultimo inserito (rocky balboa).

Proviamo a formulare la cosa diversamente e + semplicemente
allora se io faccio girare il seguente programmino

B4X:
Sub Globals
    'These global variables will be redeclared each time the activity is created.
    'These variables can only be accessed from this module.
   
    Dim tizio, caio, sempronio As persona

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")
   
    tizio.nome = "paolino"
    tizio.cognome = "paperino"
    Msgbox(tizio.nome & " " & tizio.cognome, "")
    caio = tizio
    Msgbox(caio.nome & " " & caio.cognome, "")
    tizio.nome = "rocky"
    tizio.cognome = "balboa"
    Msgbox(caio.nome & " " & caio.cognome, "")
   
End Sub

la prima msgbox visualizza paolino paperino
la seconda msgbox visualizza sempre paolino paperino
la terza, invece, che dovrebbe visualizzare sempre paolino paperino (la variabile caio non viene toccata, si assegna un nuovo valore a tizio e non a caio) invece visualizza rocky balboa!!!!!!
Questo perchè l'istruzione caio = tizio non assegna il valore ma il puntatore.

La questione potrebbe quindi spostarsi in questi termini: c'è un modo per fare assegnare il valore contenuto e non il puntatore?
probabilmente la risposta è contenuta qui dentro

https://www.b4x.com/android/forum/threads/copying-an-object-not-just-a-reference.12816/

io ho provato a leggerlo e a rileggerlo ma non sono riuscito a capirlo

un saluto a tutti
fabio milano
 

fabio_linate_milano

Member
Licensed User
Longtime User
scusate ovviamente mancava la definizione di persona che ho messo nel process_globals
B4X:
Sub Process_Globals
    'These global variables will be declared once when the application starts.
    'These variables can be accessed from all modules.
   
    Type persona(nome As String, cognome As String)

End Sub
 

LucaMs

Expert
Licensed User
Longtime User
Le classi si creano in modo diverso; ID, nome e cognome sono "proprietà" della classe (diciamo caratteristiche).
Le proprietà di una classe sono routine.

B4X:
' clsPersona - Class module

Sub Class_Globals
   ' Queste variabili private servono a contenere il valore privato delle proprietà.
   ' Io uso m come prefisso, così quando leggo qualunque pezzo di codice
   ' e vedo mID so subito che questa variabile è dichiarata nella Globals,
   ' non nella routine che sto leggendo, e quindi è modificabile da qualunque routine nel modulo.
   Private mID As Int ' se tu usi byte, potrai avere solo valori da 0 a 255
   Private mNome, mCognome As String
End Sub

'Initializes the object. You can add parameters to this method if needed.
Public Sub Initialize

End Sub

'Sets/gets ID
Public Sub setID(ID As Int)
   mID = ID
End Sub
Public Sub getID As Int
   Return mID
End Sub

'Sets/gets Nome
Public Sub setNome(Nome As String)
   mNome = Nome
End Sub
Public Sub getNome As String
   Return mNome
End Sub

'Sets/gets Cognome
Public Sub setCognome(Cognome As String)
   mCognome = Cognome
End Sub
Public Sub getCognome As String
   Return mCognome
End Sub

Le coppie di routine setNomeProprietà e getNomeProprietà (è importante che set e get siano scritte in minuscolo) rappresentano appunto una proprietà di una classe.

Scrivendo:
Dim Persona As clsPersona
Persona.Initialize
Persona. <---- dopo il punto tu vedrai le proprietà (ed i metodi, ovvero routine pubbliche che non iniziano con set né con get) disponibili di questa classe clsPersona

upload_2015-9-3_0-10-51.png


Come vedi, c'è solo una proprietà Cognome, non due routine.


Dicevo che un vantaggio delle proprietà, essendo routine e non "campi" come nei tipi (Type), è che all'interno della routine puoi scrivere ciò che vuoi (ad esempio un controllo sul valore passato come parametro).
Un altro vantaggio è che se tu non vuoi che il valore della proprietà sia cambiato dall'esterno, ti basta non scrivere la routine set.
Ad esempio, se la classe clsPersona avesse una proprietà Stipendio e lo stipendio venisse calcolato all'interno della classe, non impostato da fuori:
B4X:
'globals
Private mStipendio As Double

Public getStipendio As Double
    Return mStipendio
End Sub

PRIVATE Sub CalcolaStipendio
    mStipendio = 1000 * 2
End Sub
A questo punto avresti:
Log(Persona.Stipendio) ' <--- OK
Persona.Stipendio = 1000 <--- non funzionerebbe, perché non hai scritto la routine setStipendio (volutamente).


Altro piccolo vantaggio: nell'elenco delle proprietà puoi leggere anche la descrizione della proprietà (io ho usato soltanto cose come "Sets/Gets Nome", ma puoi scrivere molto di più e meglio).
upload_2015-9-3_0-22-25.png



Fine prima parte :)

(un altro suggerimento: usare le Region. Io non l'ho fatto per farti leggere meglio il codice qui, ma se clicki sotto... ;))
B4X:
' clsPersona - Class module

Sub Class_Globals
   ' Queste variabili private servono a contenere il valore privato delle proprietà.
   ' Io uso m come prefisso, così quando leggo qualunque pezzo di codice
   ' e vedo mID so subito che questa variabile è dichiarata nella Globals,
   ' non nella routine che sto leggendo, e quindi è modificabile da qualunque routine nel modulo.
   Private mID As Int ' se tu usi byte, potrai avere solo valori da 0 a 255
   Private mNome, mCognome As String
End Sub

'Initializes the object. You can add parameters to this method if needed.
Public Sub Initialize

End Sub

#Region  + PROPERTIES

#Region  + ID
'Sets/Gets ID
Public Sub setID(ID As Int)
   mID = ID
End Sub
Public Sub getID As Int
   Return mID
End Sub
#End Region

#Region  + Nome
'Sets/Gets Nome
Public Sub setNome(Nome As String)
   mNome = Nome
End Sub
Public Sub getNome As String
   Return mNome
End Sub
#End Region

#Region  + Cognome
'Sets/Gets Cognome
Public Sub setCognome(Cognome As String)
   mCognome = Cognome
End Sub
Public Sub getCognome As String
   Return mCognome
End Sub
#End Region

#End Region
Con le Region risulterà più comodo e leggibile, come nell'immagine sotto:
upload_2015-9-3_0-33-45.png
 
Last edited:

LucaMs

Expert
Licensed User
Longtime User
Dopo tutta 'sta pappardella, sono andato a leggere meglio il tuo codice.
Il difetto è nella fase di riempimento della Map:
B4X:
tizio.Initialize
    tizio.Id = 1
    tizio.nome = "paolino"
    tizio.cognome = "paperino"
    'elenco.Add(tizio)
    rubrica.Put(tizio.id, tizio)

    tizio.Initialize
    tizio.id = 2
    tizio.nome = "rocky"
    tizio.cognome = "balboa"
    'elenco.Add(tizio)
    rubrica.Put(tizio.id, tizio)

tizio.Initialize non crea una nuova variabile, ma vuota soltanto le proprietà.
se prima di OGNI
B4X:
tizio.Initialize
metti un
B4X:
Dim tizio As clsPersona
funzionerà.


Nota che questo è un modulo di codice, solo per mia comodità ed Esempio è una funzione,
da richiamare dal Main, ad esempio.
B4X:
Sub Process_Globals
    'These global variables will be declared once when the application starts.
    'These variables can be accessed from all modules.

   ' prefisso m per "variabile a livello di modulo"
   ' e prefisso map, così leggendo so subito che è una Map e non, ad esempio, una List.
    Private mmapRubrica As Map

End Sub

Public Sub Esempio As String
    Private Risultato As String
 
    mmapRubrica.Initialize

    Dim Tizio As clsPersona
    Tizio.Initialize
    Tizio.Id = 1
    Tizio.Nome = "Paolino"
    Tizio.Cognome = "paperino"
    mmapRubrica.Put(Tizio.id, Tizio)

    Dim Tizio As clsPersona
    Tizio.Initialize
    Tizio.id = 2
    Tizio.Nome = "rocky"
    Tizio.Cognome = "balboa"
    mmapRubrica.Put(Tizio.id, Tizio)

    Dim PersonaCorrente As clsPersona
    For i = 0 To mmapRubrica.Size - 1
        PersonaCorrente = mmapRubrica.GetValueAt(i)
        Risultato = Risultato & PersonaCorrente.id & TAB & PersonaCorrente.Nome & " - " & PersonaCorrente.Cognome & CRLF
    Next

    Return Risultato

End Sub
 

LucaMs

Expert
Licensed User
Longtime User
Concludendo (come diceva Mike - mai stato simpatico :p)...

molto probabilmente anche il tuo codice iniziale funzionerebbe premettendo:
Dim singolo As persona
ad ogni
singolo.Initialize!

In compenso, adesso sai come creare le proprietà di una classe :D.

Mettiamo che tu abbia usato il Type e adesso, per ogni persona che hai in un elenco (che sia List o Map), vuoi eseguire un calcolo, come lo stipendio, ad esempio.
Come faresti?
Un buon metodo sarebbe creare un modulo, una funzione CalcolaStipendio all'interno di questo modulo e passando un oggetto di tipo persona (type) come parametro.
Se però la funzione CalcolaStipendio si trova già nella classe, hai risolto senza aggiunta di un ulteriore modulo.
Magari questo non è un esempio eclatante, ma vedrai che se crei un tipo e in seguito pensi di fare migliorie al progetto, il tutto sarà più complicato.

Pensa che Microsoft ha modificato i suoi Type, rendendoli molto simili alle classi (prima erano come i Type di B4A), proprio per motivi come quelli che ho scritto.


Amen (ah, no, questo non c'entra, hehehe)
 

fabio_linate_milano

Member
Licensed User
Longtime User
Salve

Grazie per la risposta
Sii, diciamo che hai perfettamente centrato il problema.
Nel sorgente originale caricavo la list dentro un ciclo di for, ho spostato la dichiarazione della variabile di tipo persona che uso per il caricamento da fuori a dentro il ciclio e...
funziona alla grande!
Questo mi consente di gestire il tutto con molta eleganza.
In pratica io uso questa lista di persone come struttura parallela ad una listview (chiamiamola lvPersone). Gestisco tutto dentro la lista (nuovo elemento, cancellazione, modifica) e poi la sincronizzo con la listview.
La sincronizzazione avviene semplicemente con un lvPersone.clear e ricreandola exnovo (va benissimo è veloce).
Ovviamente la list può contenere delle informazioni interne che non vengono visualizzate nella listview.
Tra le idee future c'è quella di sostituire la listview con una scrollview (ma anche la listview è molto flessibile ad esempio ho scoperto che nelle due linee che mette a disposizione si può anche andare a capo) e poi sostituire (come mi insegni) la type con una classe.

un saluto
p.s. buon caffè (l'hai ricevuto?)
 

LucaMs

Expert
Licensed User
Longtime User
Per il caffè... grazie, non ho guardato, poi ti faccio sapere (nel frattempo si sarà freddato :D).

Per la ListView... ti consiglio vivamente la classe CheckList di @Informatix. Una volta che avrai dato un'occhiata ai suoi esempi, vedrai che non ne potrai più fare a meno
(inoltre, essendo una classe e non una libreria, si può modificare a piacimento).
Nota che non è obbligatorio utilizzare/visualizzare le CheckBox.
 

fabio_linate_milano

Member
Licensed User
Longtime User
Salve

ho avuto poco tempo per lavorarci ma sono andato avanti nel progettino (grazie ancora per l'aiuto)
Devo dire che questo meccanismo dei puntatori in B4A è abbastanza perverso, non tanto per il meccanismo in sè ma perché non ci si rende conto che si ha a che fare con dei puntatori invece che con dei valori (per me perlomeno).
Adesso appare una listview con un elenco anagrafico di prova quando clicco appare un'altra form per fare l'editing
le due form comunicano tra di loro attraverso un buffer di tipo persona
quando clicco sulla listview e voglio trasferire i dati nel buffer se faccio

buffer = gruppo.get(position)

sbagliavo in quanto il buffer punta all'elemento da modificare ma se poi faccio delle altre modifiche al buffer l'elemento che ho editato prima cambiava di conseguenza.
Ho creato questa subroutine

Sub copyPersona(target As persona, source As persona)

target.id = source.id
target.nome = source.nome
target.cognome = source.cognome
target.indirizzo = source.indirizzo
target.cap = source.cap
target.localita = source.localita
target.prov = source.prov

End Sub

e l'istruzione di prima diventa:

copyPersona(buffer, gruppo.Get(position))

così funziona tutto bene.

Mi piacerebbe adesso introdurre delle ricerche.
Mi piacerebbe farlo facendo apparire la textbox nella actionbar
una cosa tipo questa per intenderci

upload_2015-9-15_17-18-23.png


è complesso?
bisogna usare librerie strane? c'è qualche esempio in linea

un saluto
fabio milano
 

LucaMs

Expert
Licensed User
Longtime User
Devo dire che questo meccanismo dei puntatori in B4A è abbastanza perverso, non tanto per il meccanismo in sè ma perché non ci si rende conto che si ha a che fare con dei puntatori invece che con dei valori (per me perlomeno).
Tutti (penso) i linguaggi ad oggetti funzionano in questo modo, non solo b4a.

Sub copyPersona(target As persona, source As persona)
Ottima soluzione al problema in generale.
Nel tuo caso, la ListView, puoi risolvere anche ottenendo direttamente l'oggetto nell'evento ItemClick della ListView.
Quando aggiungi un Item, usa la versione 2 dei comandi Addxxx:
upload_2015-9-15_17-28-35.png




Per quanto riguarda le Action bar, sto per bestemmiare: mai usate.

Ci sono diverse librerie per questo. Posso solo suggerirti di usare una SearchView invece di una normale EditText.

Se invece vuoi cercare, ad esempio, una persona tramite il suo cognome completo, potresti usare una map per contenere gli oggetti Persona.

Dim mapPersone As Map
mapPersone.Initialize
mapPersone.Put("Messina", OggettoPersona)

Log(mapPersone.ContainsKey("Messina"))

(Risultato: False, ma solo perché Messina non è il mio cognome :D)

[P.S. Dim PersonaTrovata As Persona = mapPersone.Get("Messina")]

Ah, ho riletto in parte il thread ed ho visto che già usi le Map, quindi suggerimento sparato a vuoto, hehehe. Beh, tanto non ho sprecato inchiostro :p
 
Last edited:

fabio_linate_milano

Member
Licensed User
Longtime User
Salve a tutti

grazie per il feedback

Le librerie non sembrano così facili da usare, mancano anche degli esempi da provare.
Certo che pensandoci bene un'idea potrebbe anche essere quella di impostare la non visualizzazione della action bar mediante
#IncludeTitle: False
piazzare in alto nella activity un panel e ...
...gestire il tutto diciamo "a mano".
Nel mio caso non c'è un menu ma solo icone ed etichette ... potrebbe essere una strada percorribile.

Un altro problema è che la listview non supporta il concetto di elemento corrente da selezionare.
Adesso quando si clicca attiva subito una modalità modifica (mediante una startActivity appare il form di modifica).
mi sarebbe piaciuto mostrare un menu contestuale dove far scegliere cosa fare (eliminazione oppure modifica).
Qualcosa tipo questo per intenderci

upload_2015-9-18_18-29-23.png


Dentro la libreria dialogs non ho trovato niente. Dove devo cercare?

un saluto
fabio milano
 

udg

Expert
Licensed User
Longtime User
Ciao Fabio,

permettimi un paio di riflessioni in merito alle Action bar. Come puoi leggere da te nella documentazione ufficiale, le Action bar hanno un layout e delle caratteristiche ben precise. Io stesso, tempo fa, realizzai una libreria per avere una AB "più flessibile", ma alla fine dovetti considerare l'idea di presentarla come una Command bar più che una Action bar.
Direi che sei in una condizione molto simile. Avresti bisogno di una Command bar (un termine che ho coniato all'epoca, non so se corrisponda a qualche oggetto ufficiale) o di un qualcosa che potremmo chiamare Header Polifunzionale (in effetti un bel nome, quasi quasi lo brevetto..eheh..in inglese potrebbe essere PAH, Polyfunctional App Header).
Intanto prova a dare un'occhiata alla dgActionBar che quanto meno ti permette di posizionarla dove ti pare, lasciando libero lo spazio in alto per un pannellino di search.
Sempre che le altre funzionalità di una AB ti siano necessarie.
Non ti propongo di attendere che io possa integrare la search box nella libreria semplicemente perché al momento non ho sufficiente tempo da dedicare ai progetti B4A.

Ho comunque una curiosità in merito all'immagine del tuo post #12: come mai vedo sia la search box che l'icona della lente di ricerca? Hanno due funzioni diverse oppure, cliccando la lente, la search si sovrappone ad altre icone presenti?

Un saluto a te e a tutto il forum.. UUUHHHHHHHUUUUU
 

fabio_linate_milano

Member
Licensed User
Longtime User
Salve a tutti

grazie per il feedback
In primo luogo ho avuto modo di guardare la libreria, per il momento mi sono limitato a far "girare" gli esempi (Ex3 non ci sono riuscito, non riesce a riconoscermi la classe cl_dgpickers). Molto interessante. In particolare ho apprezzato (utile e funzionale) la possibilità di far scorrere le voci del menu.
In merito alla immagine del post #12 appunto non è mia, l'ho trovata googlando, l'ho messa per farmi capire meglio: il mio obiettivo è quello di ottenere una cosa simile.
Ho provato a percorre la strada che mi proponevo con il post #12 e sono riuscito ad ottenere qualcosa.
questo:

upload_2015-9-21_15-37-48.png


questo è il sorgentino (che ho allegato come zip):

B4X:
#Region  Project Attributes
    #ApplicationLabel: B4A Search text example
    #VersionCode: 1
    #VersionName:
    'SupportedOrientations possible values: unspecified, landscape or portrait.
    #SupportedOrientations: unspecified
    #CanInstallToExternalStorage: False
#End Region

#Region  Activity Attributes
    #FullScreen: False
    #IncludeTitle: False
#End Region

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 ime As IME
   
    ime.Initialize("")
   
    Private txtSearch As EditText
    Private lblMessaggio As Label
    Private ivIconaNO As ImageView
    Private ivIconaSearch As ImageView
    Private ivIconaSI As ImageView
   
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("main")

End Sub

Sub Activity_Resume

End Sub

Sub Activity_Pause (UserClosed As Boolean)

End Sub

Sub ivIconaSearch_Click
   
    ivIconaSearch.Visible = False
    ivIconaNO.Visible = True
    ivIconaSI.Visible = True
    txtSearch.Text = "" 'clear previuos search
    txtSearch.Visible = True
    ime.ShowKeyboard(txtSearch)
    'txtSearch.RequestFocus
   
End Sub

Sub txtSearch_EnterPressed
   
    ivIconaSearch.Visible = True
    ivIconaNO.Visible = False
    ivIconaSI.Visible = False
    ime.HideKeyboard
    txtSearch.Visible = False
    lblMessaggio.Text = "Ricerca in corso..."
   
End Sub

Sub ivIconaSI_Click
   
    ivIconaSearch.Visible = True
    ivIconaNO.Visible = False
    ivIconaSI.Visible = False
    ime.HideKeyboard
    txtSearch.Visible = False
    lblMessaggio.Text = "Ricerca di " & txtSearch.Text & " in corso..."
   
End Sub

Sub ivIconaNO_Click
   
    ivIconaSearch.Visible = True
    ivIconaNO.Visible = False
    ivIconaSI.Visible = False
    ime.HideKeyboard
    txtSearch.Visible = False
    lblMessaggio.Text = "Ricerca annullata"
   
End Sub
Nel semplice progettino che mi sono proposto direi che va più che bene.
La cosa è statica ma inserendo pochi parametri si può almeno decidere il colore e l'altezza.
Io continuo a chiamarla Action Bar nel senso che (anche se in modo più ridotto) fa le sue funzioni.

un saluto a tutti
 

Attachments

  • searchtest.zip
    34.4 KB · Views: 265

udg

Expert
Licensed User
Longtime User
Ciao Fabio,
mi fa piacere vedere che per ora il problema è risolto.
In merito alla classe cl_dgpickers dell'esempio 3, fa parte della libreria dgPickers. In effetti la dgActionBar è nata proprio per permettermi di utilizzare la dgPickers su una delle icone, cosa che non potevo fare con la Compact Actionbar di NjDude che mi piaceva molto.
 
Top