Autore Topic: Filtrare una PagedList (Room, ViewModel, LiveData)  (Letto 201 volte)

Offline Ohmnibus

  • Utente senior
  • ****
  • Post: 804
  • Respect: +168
    • Github
    • Google+
    • @ohmnibus
    • Mostra profilo
    • Lords of Knowledge GdR
  • Dispositivo Android:
    Huawei P9 Lite
  • Play Store ID:
    Ohmnibus
  • Sistema operativo:
    Windows 10 x64
Filtrare una PagedList (Room, ViewModel, LiveData)
« il: 03 Gennaio 2018, 17:19:53 CET »
0
Salve, per prendere mano con i nuovi componenti architetturali (Room, LiveData, ViewModel) per Android ho scritto una app di esempio del tutto simile a questa (ma in java).

A questa app, che carica e mostra un elenco di elementi, vorrei aggiungere un filtro di ricerca, ma non sono riuscito a trovare una soluzione elegante.

Al momento quando cambia la stringa di ricerca creo una nuova istanza di LiveData<PagedList<T>> con i risultati della ricerca, rimuovo tutti gli observer dal vecchio LiveData e li rimetto nel nuovo, in modo che possano continuare ad intercettare eventuali modifiche ai dati sottostanti.

Codice (Java): [Seleziona]
                        @Override
                        public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
                                //Rimuove gli observers dalla vecchia lista
                                viewModel.getMessageList().removeObservers(MainActivity.this);
                                //Imposta la nuova stringa di ricerca e richiede la creazione di una nuova lista
                                viewModel.setSearchString(charSequence.toString());
                        }

Codice (Java): [Seleziona]
                //Osserva i cambiamenti alla stringa di ricerca.
                //Quando cambia si mette ad osservare la nuova lista
                viewModel.getSearchString().observe(this, new Observer<String>() {
                        @Override
                        public void onChanged(@Nullable String s) {
                                viewModel.getMessageList().observe(MainActivity.this, new Observer<PagedList<Message>>() {
                                        @Override
                                        public void onChanged(@Nullable PagedList<Message> messages) {
                                                mAdapter.setList(messages);
                                        }
                                });
                        }
                });

Codice (Java): [Seleziona]
public class MyViewModel extends ViewModel {
       
        //...inizializzazione

        public final void setSearchString(String searchString) {
                //Annulla la lista così ne verrà creata una nuova
                filteredMessagesList = null;
                //Notifica la modifica della stringa di ricerca
                searchText.setValue(searchString);
        }

        public final LiveData<PagedList<Message>> getMessageList() {
                if (filteredMessagesList == null) {
                        //Ottengo la factory di DataSource tramite room
                        MessageDao msgDao = MyDatabase.getInstance(RemoteTestApp.getContext()).messageDao();
                        DataSource.Factory<Integer, Message> ds = msgDao.getFilteredPaged(searchText.getValue());
                        //Creo una nuova istanza di LiveData<PagedList<Message>>
                        filteredMessagesList = new LivePagedListBuilder<>(ds, 20).build();
                        //E' possibile parametrizzare la DataSource.Factory?
                }
                return filteredMessagesList;
        }

}

Dato che applicare un filtro equivale ad una modifica del DataSource contenuto nella PagedList, non c'è modo di applicare un filtro alla query (e rieseguirla) senza dover creare una nuova istanza della PagedList?
Ohmnibus
Le mie app su Play Store

È stata trovata una soluzione al tuo problema? Evidenzia il post più utile premendo . È un ottimo modo per ringraziare chi ti ha aiutato.

Offline iClaude

  • Utente normale
  • ***
  • Post: 311
  • Respect: +25
    • Mostra profilo
  • Dispositivo Android:
    Samsung Galaxy S8
  • Sistema operativo:
    Windows 10
Re:Filtrare una PagedList (Room, ViewModel, LiveData)
« Risposta #1 il: 09 Gennaio 2018, 11:47:20 CET »
0
Dato che devi applicare un filtro alla lista di risultati, hai pensato di prendere la lista originale e filtrarla, anziché rieseguire la query sul database?
Mi viene in mente:
- java8: metodi stream e filter
- rxjava2 (che si può usare con gli architecture components): c'è l'Operator filter che si può applicare agli Observable

È solo un'idea, non so se può fare al caso tuo...

Offline Ohmnibus

  • Utente senior
  • ****
  • Post: 804
  • Respect: +168
    • Github
    • Google+
    • @ohmnibus
    • Mostra profilo
    • Lords of Knowledge GdR
  • Dispositivo Android:
    Huawei P9 Lite
  • Play Store ID:
    Ohmnibus
  • Sistema operativo:
    Windows 10 x64
Re:Filtrare una PagedList (Room, ViewModel, LiveData)
« Risposta #2 il: 09 Gennaio 2018, 14:13:45 CET »
0
Il problema è che il risultato è una lista paginata (PagedList) e non credo (o non so come) si possa applicare un filtro.

Comunque provo ad informarmi su quanto mi hai consigliato.
Ohmnibus
Le mie app su Play Store

È stata trovata una soluzione al tuo problema? Evidenzia il post più utile premendo . È un ottimo modo per ringraziare chi ti ha aiutato.