SQLite
 sql >> Database >  >> RDS >> SQLite

come ottenere il primo o (qualsiasi) elemento da un elenco LiveData nell'architettura MVVM di Android?

come ottenere il primo o (qualsiasi) elemento da un elenco LiveData nell'architettura AndroidMVVM

Se vuoi ottenere un elemento particolare da un elenco LiveData, devi limitare la tua query con un offset.

Per impostazione predefinita, la limitazione di una query non considera un offset ad essa; quindi il valore di offset predefinito è 0.

Ad esempio, nel tuo Dao :

Le query seguenti dell'Esempio 1 e 2 sono equivalenti, poiché il valore di offset predefinito è 0.

Esempio

@Query("SELECT * FROM students LIMIT  :limit")
LiveData<List<Student>> getStudents(int limit);

// Query
getStudents(1); // returns the first row of the list

Esempio 2

@Query("SELECT * FROM students LIMIT  :limit OFFSET :offset")
LiveData<List<Student>> getStudents(int limit, int offset);

// Query
getStudents(1, 0); // returns the first row of the list

Nota: Qui presumo che la tua classe modello sia Student

Si tratta della prima riga; ma per restituire il numero di riga x quindi devi manipolare l'offset in modo che sia:x-1 , poiché l'offset è un valore in base 0

Esempio 3 (stessa query Dao dell'esempio 2)

getStudents(1, 1); // returns the second row
getStudents(1, 4); // returns the fifth row

Se vuoi restituire più di una riga, devi modificare il LIMIT valore, quindi per restituire x righe dai risultati, quindi limita la query con x .

getStudents(2, 1); // returns the second and third rows
getStudents(3, 4); // returns the fifth, sixth, and seventh rows

Spero che questo risponda alla tua domanda

Modifica come da commenti

Ho già un elenco restituito da un'altra query @Query("SELECT * FROM students) LiveData<List<Student>> getStudents(); Quindi il valore restituito è un elenco. Voglio ottenere il primo elemento dall'elenco. Questa risposta restituisce veramente il primo elemento, ma devo passare tutti i passaggi (per definire questo metodo in ViewModel classe e osservarlo in MainActivity per ottenere l'elenco o qualsiasi elemento nell'elenco). Quello di cui ho bisogno è digitare il primo valore nell'elenco mentre mi diverto con la funzione nella classe repository. –

Ora stai usando la query sottostante

@Query("SELECT * FROM students")
LiveData<List<Student>> getStudents();

E tu vuoi:

  1. Ottieni il primo o qualsiasi elemento nell'elenco. e di farlo secondo quanto sopra indicato
  2. Supera tutti i passaggi (per definire questo metodo in ViewModel classand osservalo in MainActivity per ottenere la lista o qualsiasi elemento della lista).

Quindi per farlo:

In Dao: :cambia la tua query in

@Query("SELECT * FROM students LIMIT  :limit OFFSET :offset")
LiveData<List<Student>> getAllStudents(int limit, int offset);

Nel repository:

public class StudentRepository {

    ...

    public LiveData<List<Student>> getAllStudents(final int limit, final int offset) {
        return mDAO.getAllStudents(limit, offset);
    }
}

In ViewModel:

public LiveData<List<Student>> getAllStudents(final int limit, final int offset) {
    return mRepository.getAllStudents(limit, offset);
}

In attività:

private void getAllStudents(int limit, int offset) {
    mViewModel.getAllStudents(limit, offset).observe(this, new Observer<List<Student>>() {
        @Override
        public void onChanged(List<Student> students) {
            if (students != null) {
                // Here you can set RecyclerView list with `students` or do whatever you want

            }
        }
    });
}

E per verificarlo:

getAllStudents(1, 0); // return first row from the table.
getAllStudents(2, 0); // return first 2 rows from the table.
getAllStudents(2, 1); // return 2nd and 3rd rows from the table.
getAllStudents(-1, 5); // remove first 5 rows from the table.

E per restituire il primo elemento dell'elenco mAllStudents per digitare il nome del primo studente nel Log.d

Quindi, nella tua attività

mViewModel.getAllStudents(1, 0).observe(this, new Observer<List<Student>>() {
    @Override
    public void onChanged(List<Student> students) {
        if (students != null) {
            Student student = students.get(0);
            Log.d("First_Name", student.getName());
        }
    }
});

Modifica è possibile restituire qualsiasi elemento dell'elenco senza seguire tutti i passaggi come scrivere una funzione nel ViewModel e osservarlo in MainActivity? La mia domanda è di non seguire tutti i passaggi.

Sì, è possibile, ma il modello sopra è il modello consigliato da Google. Puoi restituire un List<Student> da Dao query invece di LiveData<List<Student>> , ma le cattive notizie sono:

  1. Devi gestirlo in un thread in background separato; perché il LiveData fallo gratuitamente.
  2. Perderai il valore di LiveData; quindi devi aggiornare manualmente l'elenco per controllare eventuali aggiornamenti poiché non sarai in grado di utilizzare il modello di osservatore.

Quindi, puoi omettere l'utilizzo di ViewModel e Repository , ed esegui tutte le operazioni dell'attività come segue:

private Executor mExecutor = Executors.newSingleThreadExecutor();

public void getAllStudents(final int limit, final int offset) {

    final StudentDAO mDAO = StudentDatabase.getInstance(getApplicationContext()).getStudentDAO();

    mExecutor.execute(new Runnable() {
        @Override
        public void run() {
            List<Student> students = mDAO.getAllStudents(limit, offset);
            Student student = students.get(0);
            Log.d("First_Name", student.getName());
        }
    });
}

// Usage: getAllStudents(1, 0);

E la domanda per il Dao:

@Query("SELECT * FROM students LIMIT  :limit OFFSET :offset")
List<Student> getAllStudents(int limit, int offset);