Visualizzazione stampabile
-
CursorAdapter e Filter
Creo un'altra discussione visto che l'argomento è un po' diverso da quello dell'altro giorno...
Ho una ListView popolata tramite un cursore che fa una select sul DB.
Utilizzo una mia classe che estende CursorAdapter, fin qui tutto normale.
Ora però vorrei poter filtrare i dati in base al valore di alcuni campi (es: "colonnaX=1"), sull'Adapter esiste un metodo getFilter che restituisce un oggetto di tipo Filter che ha un metodo filter(CharSequence) che dovrebbe servire a filtrare i risultati, ma come dovrebbe essere usato con un cursore??
Ho provato a fare una cosa del genere:
ma non ha funzionato, vedo sempre tutti i risultati... ho provato pure aggiungendo questo:
ma niente ancora.
In un'altra applicazione avevo una ListView popolata da un ArrayAdapter e ho dovuto estendere Filter e nel metodo performFiltering() scorrevo l'array e restituivo i dati che volevo, ma col cursore come si dovrebbe fare?
-
Quote:
Originariamente inviato da
Orochi
In un'altra applicazione avevo una ListView popolata da un ArrayAdapter e ho dovuto estendere Filter e nel metodo performFiltering() scorrevo l'array e restituivo i dati che volevo, ma col cursore come si dovrebbe fare?
Hai trovato qualche esempio sui filter? Purtroppo google restituisce dozzine di pagine con gli intent filter :-[ e l'argomento è interessante.
Secondo me, comunque, una reimplementazione è comunque necessaria. Qual è il problema con i cursori? Sono una classe diversa dall'array, ma anche loro hanno i loro bei metodi per pastrugnarli, no?
-
Sì, l'avevo trovato qualche esempio, non ricordo dove, comunque ho il codice che ho scritto l'altra volta, avevo esteso le classi ArrayAdapter e Filter, e dentro l'adapter conservavo l'array con i dati completi e con quelli filtrati, nel Filter nel metodo performFiltering() non si fa altro che scorrere l'array e riempire l'array dei risultati da restituire nella struttura di ritorno (che in questo istante non ricordo di che tipo è). Se ti interessa dimmelo che lo posto.
Il mio dubbio sull'uso del cursore è evitare di fare "schifezze" poco ottimizzate scorrendo e riscorrendo il cursore per poi restituire non so neanche che cosa fuori.... un altro cursore?
Non so, magari l'unico modo è rifare la query da capo, ma mi sembra stupido e poco ottimizzato..
Purtroppo esempi con filter per CursorAdapter non li ho trovati :'(
-
Quote:
Originariamente inviato da
Orochi
Se ti interessa dimmelo che lo posto.
Se non è supersegreto sarebbe una bella cosa, in questo forum dopotutto si imparano sempre cose nuove! :cool:
Quote:
Originariamente inviato da
Orochi
Il mio dubbio sull'uso del cursore è evitare di fare "schifezze" poco ottimizzate scorrendo e riscorrendo il cursore per poi restituire non so neanche che cosa fuori.... un altro cursore?
Non so, magari l'unico modo è rifare la query da capo, ma mi sembra stupido e poco ottimizzato..
Purtroppo esempi con filter per CursorAdapter non li ho trovati :'(
Rifare la query potrebbe essere in realtà, il metodo più ottimizzato perché non c'è niente di più agile di un DB per cercare le robe. Ovviamente, da un punto di vista di programmazione potrebbe non essere il metodo più pulito (se si trattasse di una query da ripetere molte volte o in più punti, sicuramente) e sicuramente in una selezione java potresti mettere un'intelligenza diversa, magari più facilmente che tramite SQL.
Per quello che riguarda il cursor... bhe, da quello che vedo alla fine la performFilter restituisce un FilterResult quindi puoi sentirti libero di recuperare il risultato nella forma migliore che credi, anche non un Cursore. Per quello che riguarda manipolare il cursore di partenza, invece, non credo che sia molto più sporco che maneggiare un array, anzi, dovrebbe avere metodi migliori...
-
Ho risolto!!!!!!!!
All'inizio ho trovato questo sistema che è praticamente uno di quelli usati quando si lavora con i content providers per fare tipo il filtro dei dati con l'autocompletamento, non è proprio quello che dovevo fare io, ma il risultato è lo stesso, filtrare i dati:
Qui db è la mia classe helper per il database. Successivamente nella onClick di qualche bottone dell'activity faccio questo:
In pratica la stringa myFilter viene passata come parametro constraint al metodo runQueryOnBackgroundThread che effettua di nuovo la query.
Il problema di questa soluzione è quello che dicevo prima, creo un nuovo cursore, incorporo nell'adapter persino la chiamata alla classe helper per fare ciò, ed è una schifezza immane! :p
Fortunatamente però spulciando tra i javadoc dell'SDK ho visto per caso che esisteva questo metodo:
Problema: il metodo è presente solo nella classe SQLiteCursor... e quando si eseguono le query si ottiene una generica interfaccia Cursor che in realtà è una classe wrapper diversa da cui non è possibile ottenere/castare quell'oggetto lì!
Dopo un po' di sbattimenti e un errore visto nel LogCat riguardo un "Leak", in pratica non chiudevo bene i cursori roftl, sono andato a cercare cosa fare per chiudere questi benedetti cursori e ho scoperto che il metodo startManagingCursor dell'activity che pensavo lo facesse lei in realtà non lo fa, e da qui cercando la soluzione a questo problema ho trovato pure la soluzione all'altro!
Per assicurarsi di chiudere la connessione all'SQLiteDatabase, un tizio estendeva un po' di classi (compreso il cursore) per poter poi mantenere nel cursore il riferimento al db e chiamarci la close() nel metodo close() del cursore. La cosa interessante è che per fare ciò ha esteso la CursorFactory per farsi restituire il proprio cursore custom, ed ecco risolto il problema!
Un po' di codice vale più di 1000 parole ;)
Quindi tutto questo casino non fa altro che cambiare il parametro args che ho passato prima alla query dal mio metodo readList(String selectionArg) rieseguendo la stessa query roftlroftl
Alla fine la query credo la faccia lo stesso, ma non rialloca niente, riutilizza al massimo l'adapter, il cursore, la connessione al db, ecc... e credo che sia anche il sistema "giusto" da seguire in questo caso!
E' stata una faticaccia, ma che soddisfazione :D
Alla faccia dei tutorial online!
Spero che sia utile a qualcun'altro tutto questo popo' di codice ;)